2015-07-17 3 views
5

Как и на этот вопрос How to add an empty column to a dataframe?, я заинтересован в том, чтобы узнать, как добавить столбец пустых списков в DataFrame.Добавить столбец пустых списков в DataFrame

То, что я пытаюсь сделать, это в основном инициализировать столбец и, когда я перебираю строки для обработки некоторых из них, затем добавьте заполненный список в этот новый столбец, чтобы заменить инициализированное значение.

Например, если ниже мой первоначальный DataFrame:

df = pd.DataFrame(d = {'a': [1,2,3], 'b': [5,6,7]}) # Sample DataFrame 

>>> df 
    a b 
0 1 5 
1 2 6 
2 3 7 

Тогда я хочу, чтобы в конечном счете, в конечном итоге с чем-то вроде этого, где каждая строка была обработана отдельно (показан пример результатов):

>>> df 
    a b   c 
0 1 5  [5, 6] 
1 2 6  [9, 0] 
2 3 7 [1, 2, 3] 

Конечно, если я попытаюсь инициализировать как df['e'] = [] так же, как и с любой другой константой, он думает, что я пытаюсь добавить последовательность элементов длиной 0 и, следовательно, терпит неудачу.

Если я попытаюсь инициализировать новый столбец как None или NaN, при попытке присвоить список местоположению я столкнулся со следующими проблемами.

df['d'] = None 

>>> df 
    a b  d 
0 1 5 None 
1 2 6 None 
2 3 7 None 

Выпуск 1 (это было бы идеально, если я могу получить этот подход к работе Может быть что-то тривиальное мне не хватает!):

>>> df.loc[0,'d'] = [1,3] 

... 
ValueError: Must have equal len keys and value when setting with an iterable 

Выпуск 2 (это работает, но не без предупреждения потому что он не гарантированно работает по назначению):

>>> df['d'][0] = [1,3] 

C:\Python27\Scripts\ipython:1: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame 

Поэтому я прибегаю к инициализации пустых списков и расширению их по мере необходимости. Есть несколько методов, которые я могу придумать, чтобы инициализировать этот путь, но есть ли более простой способ?

Метод 1:

df['empty_lists1'] = [list() for x in range(len(df.index))] 

>>> df 
    a b empty_lists1 
0 1 5    [] 
1 2 6    [] 
2 3 7    [] 

Метод 2:

df['empty_lists2'] = df.apply(lambda x: [], axis=1) 

>>> df 
    a b empty_lists1 empty_lists2 
0 1 5    []    [] 
1 2 6    []    [] 
2 3 7    []    [] 

Резюме вопросов:

Есть ли незначительные изменения синтаксиса, которые могут быть рассмотрены в выпуске 1, что может позволить список, который должен быть присвоен инициализированному полю None/NaN?

Если нет, то каков наилучший способ инициализировать новый столбец пустыми списками?

+0

в выпусках 1 и 2 вы начинаете ссылаться на столбец d. к чему это относится? – AZhao

+0

и за что его стоит мне нравится подход 2. довольно простой imo. – AZhao

+0

Столбец '' d''- это только столбец инициализированных значений' None' или 'NaN', как определено непосредственно перед проблемами. – vk1011

ответ

11

Еще один способ заключается в использовании np.empty:

df['empty_list'] = np.empty((len(df), 0)).tolist() 

Вы также могли бы сбить .index в вашем "Метод 1" при попытке найти len из df.

df['empty_list'] = [[] for _ in range(len(df))] 

Оказывается, np.empty быстрее ...

In [1]: import pandas as pd 

In [2]: df = pd.DataFrame(pd.np.random.rand(1000000, 5)) 

In [3]: timeit df['empty1'] = pd.np.empty((len(df), 0)).tolist() 
10 loops, best of 3: 127 ms per loop 

In [4]: timeit df['empty2'] = [[] for _ in range(len(df))] 
10 loops, best of 3: 193 ms per loop 

In [5]: timeit df['empty3'] = df.apply(lambda x: [], axis=1) 
1 loops, best of 3: 5.89 s per loop 
+0

Спасибо. Да, подход 'np.empty' выглядит быстрее. 'Len (df.index)' также на самом деле аналогично быстрее, чем просто len (df) '. – vk1011

2

Я приурочил все три метода в принятом ответе, самый быстрый из них занял 216 мс на моей машине. Тем не менее, это заняло всего 28 мс:

df['empty4'] = [[]] * len(df)

Примечание: Аналогично, df['e5'] = [set()] * len(df) также приняли 28ms.

+0

Я пытался понять это в течение 2 часов, это решение является реальной сделкой. – JoelBondurant

Смежные вопросы