#python #pandas #indexing
#python #pandas #индексирование
Вопрос:
Я пытаюсь создать сводный фрейм данных, но способ его заполнения вызывает проблемы, потому что на ярлыках не выполняется проверка.
Вот пример игрушки:
import numpy as np
import pandas as pd
arrays = [np.hstack([ ['one']*3, ['two']*3]), ['Dog', 'Bird', 'Cat']*2]
columns = pd.MultiIndex.from_arrays(arrays, names=['foo', 'bar'])
df = pd.DataFrame(np.zeros((3,6)),columns=columns,
index=pd.date_range('20000103',periods=3))
df['one'] = pd.DataFrame({'Bird' : np.ones(3)*2,
'Dog' : np.ones(3),
'Cat' : np.ones(3)*3},
index= pd.date_range('20000103',periods=3))
df['two'] = pd.DataFrame({'Dog' : np.ones(3)*4,
'Bird' : np.ones(3)*5,
'Cat' : np.ones(3)*6,},
index= pd.date_range('20000103',periods=3))
Результат таков:
foo one two
bar Dog Bird Cat Dog Bird Cat
2000-01-03 2 3 1 5 6 4
2000-01-04 2 3 1 5 6 4
2000-01-05 2 3 1 5 6 4
Где я ожидал бы:
foo one two
bar Dog Bird Cat Dog Bird Cat
2000-01-03 1 2 3 4 5 6
2000-01-04 1 2 3 4 5 6
2000-01-05 1 2 3 4 5 6
Проблема в том, что фрейм отсортирован в алфавитном порядке по столбцам. Затем он вставляется в больший фрейм с отсортированными значениями, и тогда метка столбца становится неправильной.
Итак, мой вопрос в том, есть ли способ убедиться, что метки столбцов совпадают?
Ответ №1:
Это должно выровняться по уровням (хотя существует некоторая двусмысленность, как это сделать, например, на каком уровне). https://github.com/pydata/pandas/issues/7655
Вы должны сделать это вместо:
In [10]: one = pd.DataFrame({'Bird' : np.ones(3)*2,
'Dog' : np.ones(3),
'Cat' : np.ones(3)*3},
index= pd.date_range('20000103',periods=3))
In [11]: two = pd.DataFrame({'Dog' : np.ones(3)*4,
....: 'Bird' : np.ones(3)*5,
....: 'Cat' : np.ones(3)*6,},
....: index= pd.date_range('20000103',periods=3))
In [12]: one
Out[12]:
Bird Cat Dog
2000-01-03 2 3 1
2000-01-04 2 3 1
2000-01-05 2 3 1
In [13]: two
Out[13]:
Bird Cat Dog
2000-01-03 5 6 4
2000-01-04 5 6 4
2000-01-05 5 6 4
In [14]: concat([one,two],keys=['one','two'],axis=1)
Out[14]:
one two
Bird Cat Dog Bird Cat Dog
2000-01-03 2 3 1 5 6 4
2000-01-04 2 3 1 5 6 4
2000-01-05 2 3 1 5 6 4
Комментарии:
1. В итоге я просто добавил columns = df [‘one’], как предложено ниже. Я думал, что это будет сделано автоматически. Возможно, принудительное выполнение этого назначения — лучший способ исправить это. По крайней мере, это выдало бы ошибку, если бы они не совпадали.
Ответ №2:
Одним из способов было бы изменить порядок столбцов вашего временного фрейма данных по мере его назначения, используя порядок столбцов из большего фрейма данных.
In [50]: df['one'] = pd.DataFrame({'Bird' : np.ones(3)*2,
'Dog' : np.ones(3),
'Cat' : np.ones(3)*3},
index= pd.date_range('20000103',periods=3))
[df['one'].columns]
In [51]: df['two'] = pd.DataFrame({'Dog' : np.ones(3)*4,
'Bird' : np.ones(3)*5,
'Cat' : np.ones(3)*6,},
index= pd.date_range('20000103',periods=3))
[df['two'].columns]
In [52]: df
Out[52]:
foo one two
bar Dog Bird Cat Dog Bird Cat
2000-01-03 1 2 3 4 5 6
2000-01-04 1 2 3 4 5 6
2000-01-05 1 2 3 4 5 6