Дано два массива:

x
[('010_628', '2543677'), ('010_228', '2543677'), ('015_634', '2543677')]

y 
array([['me', 10228955],
       ['me', 10228955],
       ['me', 10228955]], dtype=object)

В настоящее время этот код возвращает мне фрейм данных с плоским индексом кортежей:

df = pd.DataFrame(x, index=y, columns=['pm_code',   'sec_pm'])
df
                pm_code   sec_pm
(me, 10228955)  010_628  2543677
(me, 10228955)  010_228  2543677
(me, 10228955)  015_634  2543677

Как я могу вместо этого создать MultiIndex фрейм данных, который выглядит следующим образом?

                  pm_code   sec_pm
state site_no                     
me    10228955   010_628  2543677
                 010_228  2543677
                 015_634  2543677

Я пытался использовать pd.MultiIndex.from_tuples, но не могу понять это правильно. Спасибо за помощь.


Приложение. Сравнение производительности

Небольшой

# unutbu #1
%timeit pd.DataFrame(x, index=pd.MultiIndex.from_arrays(y.T), columns=['pm_code',   'sec_pm'])
1000 loops, best of 3: 1.25 ms per loop

# unutbu #2
%timeit pd.DataFrame(x, index=pd.MultiIndex.from_tuples(y.tolist()), columns=['pm_code',   'sec_pm'])
1000 loops, best of 3: 1.47 ms per loop

# piRSquared
%timeit pd.DataFrame(x, index=y.T.tolist(), columns=['pm_code', 'sec_pm'])
1000 loops, best of 3: 1.41 ms per loop

# Andrew L
%timeit pd.DataFrame(x, index=[y[:,0], y[:,1]], columns=['pm_code',   'sec_pm'])
1000 loops, best of 3: 1.29 ms per loop

Большой

x2 = np.repeat(x, 10000, 0)
y2 = np.repeat(x, 10000, 0)

# unutbu #1
%timeit pd.DataFrame(x2, index=pd.MultiIndex.from_arrays(y2.T), columns=['pm_code',   'sec_pm'])
100 loops, best of 3: 17.3 ms per loop

# unutbu #2
%timeit pd.DataFrame(x2, index=pd.MultiIndex.from_tuples(y2.tolist()), columns=['pm_code',   'sec_pm'])
10 loops, best of 3: 30.5 ms per loop

# piRSquared
%timeit pd.DataFrame(x2, index=y2.T.tolist(), columns=['pm_code', 'sec_pm'])
10 loops, best of 3: 37.2 ms per loop

# Andrew L
%timeit pd.DataFrame(x2, index=[y2[:,0], y2[:,1]], columns=['pm_code',   'sec_pm'])
100 loops, best of 3: 22 ms per loop

Данные из этого вопроса.

3
cs95 29 Авг 2017 в 21:58

3 ответа

Лучший ответ

Вы можете использовать pd.MultiIndex.from_arrays(y.T):

In [53]: pd.DataFrame(x, index=pd.MultiIndex.from_arrays(y.T), columns=['pm_code',   'sec_pm'])
Out[53]: 
             pm_code   sec_pm
me 10228955  010_628  2543677
   10228955  010_228  2543677
   10228955  015_634  2543677

Или pd.MultiIndex.from_tuples(y.tolist()):

In [54]: pd.DataFrame(x, index=pd.MultiIndex.from_tuples(y.tolist()), columns=['pm_code',   'sec_pm'])
Out[54]: 
             pm_code   sec_pm
me 10228955  010_628  2543677
   10228955  010_228  2543677
   10228955  015_634  2543677
5
unutbu 29 Авг 2017 в 19:29

Вариант 1
Если вы передаете список массивов, подобных вещам, конструктор знает, что с ним делать.

pd.DataFrame(x, index=y.T.tolist(), columns=['pm_code', 'sec_pm'])

    pm_code   sec_pm
me 10228955  010_628  2543677
   10228955  010_228  2543677
   10228955  015_634  2543677
2
piRSquared 29 Авг 2017 в 19:30

Вы также можете нарезать свои массивы и перейти к index:

df = pd.DataFrame(x, index=[y[:,0], y[:,1]], columns=['pm_code',   'sec_pm'])

df
             pm_code   sec_pm
me 10228955  010_628  2543677
   10228955  010_228  2543677
   10228955  015_634  2543677
2
Andrew L 29 Авг 2017 в 19:09