Панды добавить элемент в серию списка типов данных - PullRequest
0 голосов
/ 10 января 2019

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

Это мой код:

df = pd.DataFrame({'num':[['one'],['three'],['five']]})

# make copy of original df
copy_df = df.copy()

# add 'thing' to every single list
copy_df.num.apply(lambda x: x.append('thing'))

# show results of copy_df
print(copy_df) # this will show [['one', 'thing'], ['three', 'things'], ...]

print(df) # this will also show [['one', 'thing'], ['three', 'things'], ...]
# WHY? 

Мой вопрос:

  1. почему вышеописанный метод также добавляет элемент в оригинальную копию?
  2. Есть ли лучший способ добавить элемент в серию списка?

Ответы [ 3 ]

0 голосов
/ 10 января 2019

1- Указатели на списки, к которым осуществляется доступ через фрейм данных, а не сами списки. Таким образом, когда вы изменяете один список в одном кадре данных, вы изменяете все это неявно (потому что это один объект). Вы можете проверить это - посмотрите на идентификаторы списков:

copy_df = df.copy()

copy_df['num'].apply(id)
0    140262813220744
1    140262813299528
2    140262813298888
Name: num, dtype: int64

df['num'].apply(id)
0    140262813220744
1    140262813299528
2    140262813298888
Name: num, dtype: int64

2 - Лучше не хранить списки в кадре данных, но вместо этого использовать своего рода «длинную» таблицу, например:

   list_index    num
0  0            "one"
0  1          "thing"
1  0          "three"
1  1         "things"
2  0           "five"
2  1         "things"  

Вы храните те же данные, но с ними проще обращаться pandas методами.

Редактировать
Если вы будете использовать

copy_df.num = copy_df.num.apply(lambda x: x + 'num')

вернет новый фрейм данных с совершенно новыми списками:

copy_df.num
Out:
0      [one, thing]
1    [three, thing]
2     [five, thing]

copy_df.num.apply(id)
Out:
0    140262813289352
1    140262794045256
2    140262794050504

ID только что изменился!

copy.deepcopy тоже не работает:

import copy

deepcopy_df = copy.deepcopy(df)
deepcopy_df.num.apply(id)
Out:
0    140262813220744
1    140262813299528
2    140262813298888

deepcopy_df.apply(lambda x: x.append('things'))
df.num  # original DataFrame
Out:
0      [one, things]
1    [three, things]
2     [five, things]
0 голосов
/ 10 января 2019

Или нет - lambda версия ответа Сунила:

copy_df.num=copy_df.num.apply(['thing'].__add__)

Если вы заботитесь о том, чтобы 'thing' был первым:

copy_df.num=copy_df.num.apply(['thing'].__add__).str[::-1]
0 голосов
/ 10 января 2019

Поскольку вы копируете фрейм данных, а не список в фрейме данных, внутренняя серия по-прежнему имеет ссылку на список из исходного фрейма данных.

Лучший способ достичь этого;

copy_df.num = copy_df.num.apply(lambda x: x + ['thing'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...