pandas мультииндексный фрейм данных - данные, вставленные в новый столбец и подстроку, видны только в представлении столбца? - PullRequest
2 голосов
/ 15 января 2020

Я пытаюсь вставить список данных в многоуровневый pandas фрейм данных. Кажется, что он работает просто отлично, но когда я просматриваю весь фрейм данных, новой подстроки нет. Вот пример:

Создание пустого мультииндексного фрейма данных:

ind = pd.MultiIndex.from_product([['A','B','C'], ['a', 'b','c']]) #set up index 
df = pd.DataFrame(columns=['col1'], index=ind)                    #create empty df with multi-level nested index
print(df)
    col1
A a  NaN
  b  NaN
  c  NaN
B a  NaN
  b  NaN
  c  NaN
C a  NaN
  b  NaN
  c  NaN

Вставка нового столбца работает нормально:

newcol = 'col2'      #new column name
df[newcol] = np.nan  #fill new column with nans
print(df)
    col1  col2
A a  NaN   NaN
  b  NaN   NaN
  c  NaN   NaN
B a  NaN   NaN
  b  NaN   NaN
  c  NaN   NaN
C a  NaN   NaN
  b  NaN   NaN
  c  NaN   NaN

Вставка данных в существующую подстроку работает с точечными данными, но не со списком:

df[newcol]['A','a'] = 1        #works with point data but not with list
print(df)
    col1  col2
A a  NaN   1.0
  b  NaN   NaN
  c  NaN   NaN
B a  NaN   NaN
  b  NaN   NaN
  c  NaN   NaN
C a  NaN   NaN
  b  NaN   NaN
  c  NaN   NaN

Вставка в новую подстроку выглядит хорошо при просмотре только одного столбца:

df[newcol]['A','d'] = [1,2,3]  #insert into new sub-row 'd'
print(df[newcol])              #view just new column
A  a            1
   b          NaN
   c          NaN
B  a          NaN
   b          NaN
   c          NaN
C  a          NaN
   b          NaN
   c          NaN
A  d    [1, 2, 3]
Name: col2, dtype: object

Но это не видно при просмотре всего кадра данных - почему?

print(df) 
    col1  col2
A a  NaN   1.0
  b  NaN   NaN
  c  NaN   NaN
B a  NaN   NaN
  b  NaN   NaN
  c  NaN   NaN
C a  NaN   NaN
  b  NaN   NaN
  c  NaN   NaN

Кроме того, когда я пытаюсь использовать различные способы вставки данных, я сталкиваюсь с проблемами: Использование df .loc [] отлично работает для одной точки данных, но не для списков:

df.loc[('A','f'),  newcol] = 1          #create new row at [(row,sub-row),column] & insert point data
print(df)                               #works fine
    col1  col2
A a  NaN   1.0
  b  NaN   NaN
  c  NaN   NaN
B a  NaN   NaN
  b  NaN   NaN
  c  NaN   NaN
C a  NaN   NaN
  b  NaN   NaN
  c  NaN   NaN
A f  NaN   1.0

Тот же метод, но вставка списка возвращает ошибку:

df.loc[('A','f'),  newcol] = [1,2,3]    #create new row at [(row,sub-row),column] & insert list data

TypeError: object of type 'numpy.float64' has no len()

Использование df.at [] возвращает ошибку как с точками, так и со списком:

data.at[('A','f'), newcol] = [1,2,3] #insert into existing sub-row 'f'

KeyError: ('A', 'f')

1 Ответ

1 голос
/ 15 января 2020

когда вы делаете df[newcol]['A','d'] = [1,2,3], это присвоение с цепочкой-индексированием, поэтому результат непредсказуем. Pandas не гарантирует правильного поведения при цепной индексации. Когда вы запускаете эту команду, pandas выполняется с предупреждением. Это предупреждение даже включает ссылку на полное объяснение, если вы хотите знать. Я не go в деталях, потому что ссылка в предупреждении очень хорошо объясняет эту цепную индексацию.

При назначении списка ячейке всегда возникает боль. Однако это выполнимо. Я предполагаю вашу проблему с df.loc[('A','f'), newcol] = [1,2,3], потому что col2 - это dtype float, поэтому pandas не рассматривает [1,2,3] как один объект list. Он рассматривает [1,2,3] как список из нескольких числовых значений c, поэтому он потерпел неудачу. Я не знаю, является ли это ошибкой или намеренным.

Чтобы решить вашу проблему с помощью .loc, преобразуйте col2 в dtype object и выполните назначение

df['col2'] = df['col2'].astype('O')
df.loc[('A','f'),  'col2'] = [1,2,3]

print(df)

Out[1911]:
    col1       col2
A a  NaN        NaN
  b  NaN        NaN
  c  NaN        NaN
B a  NaN        NaN
  b  NaN        NaN
  c  NaN        NaN
C a  NaN        NaN
  b  NaN        NaN
  c  NaN        NaN
A f  NaN  [1, 2, 3]

print(df['col2'])

Out[1912]:
A  a          NaN
   b          NaN
   c          NaN
B  a          NaN
   b          NaN
   c          NaN
C  a          NaN
   b          NaN
   c          NaN
A  f    [1, 2, 3]
Name: col2, dtype: object
...