Используйте оригинальные индексы df1 для создания серии:
df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)
Редактировать 2015
Некоторые сообщили о получении SettingWithCopyWarning
с этим кодом.
Тем не менее, код по-прежнему отлично работает с текущей версией панды 0.16.1.
>>> sLength = len(df1['a'])
>>> df1
a b c d
6 -0.269221 -0.026476 0.997517 1.294385
8 0.917438 0.847941 0.034235 -0.448948
>>> df1['e'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
a b c d e
6 -0.269221 -0.026476 0.997517 1.294385 1.757167
8 0.917438 0.847941 0.034235 -0.448948 2.228131
>>> p.version.short_version
'0.16.1'
Целью SettingWithCopyWarning
является информирование о возможном неверном назначении на копии кадра данных. Это не обязательно говорит о том, что вы сделали это неправильно (это может привести к ложным срабатываниям), но из 0.13.0 это дает вам понять, что для этой цели есть более адекватные методы. Затем, если вы получите предупреждение, просто следуйте его совету: попробуйте вместо этого использовать .loc [row_index, col_indexer] = value
>>> df1.loc[:,'f'] = pd.Series(np.random.randn(sLength), index=df1.index)
>>> df1
a b c d e f
6 -0.269221 -0.026476 0.997517 1.294385 1.757167 -0.050927
8 0.917438 0.847941 0.034235 -0.448948 2.228131 0.006109
>>>
На самом деле, это в настоящее время более эффективный метод, как описано в pandas docs
Редактировать 2017
Как указано в комментариях @Alexander, в настоящее время наилучшим методом добавления значений Series в качестве нового столбца DataFrame может быть использование assign
:
df1 = df1.assign(e=pd.Series(np.random.randn(sLength)).values)
SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_index,col_indexer] = value instead
kwargs
словарь, например, так:df1 = df1.assign(**{'e': p.Series(np.random.randn(sLength)).values})
Это простой способ добавления нового столбца:
df['e'] = e
источник
e
(Series(np.random.randn(sLength))
) генерирует индексированную серию 0-n. Если вы назначите это для df1, то вы получите несколько ячеек NaN.my_dataframe = pd.DataFrame(columns=('foo', 'bar'))
,Я предполагаю, что значения индекса
e
совпадают со значениями вdf1
.Самый простой способ инициировать новый столбец с именем
e
и присвоить ему значения из вашей серииe
:назначить (Панды 0.16.0+)
Начиная с Pandas 0.16.0, вы также можете использовать
assign
, который назначает новые столбцы для DataFrame и возвращает новый объект (копию) со всеми исходными столбцами в дополнение к новым.Согласно этому примеру (который также включает исходный код
assign
функции), вы также можете включить более одного столбца:В контексте с вашим примером:
Описание этой новой функции, когда она была впервые представлена, можно найти здесь .
источник
df['e'] = e.values
) не создает копию кадра данных, в то время как второй вариант (использованиеdf.assign
) делает? В случае большого количества новых столбцов, добавляемых последовательно, и больших фреймов данных я бы ожидал гораздо лучшей производительности первого метода.assign
состоит в том, когда вы объединяете свои операции.df.assign(**df.mean().add_prefix('mean_'))
df_new = pd.concat([df1, df2], axis=1)
, отметив этоignore_index=False
по умолчанию.Похоже, что в последних версиях Pandas лучше всего использовать df.assign :
df1 = df1.assign(e=np.random.randn(sLength))
Это не производит
SettingWithCopyWarning
.источник
Делать это напрямую через NumPy будет наиболее эффективным:
Обратите внимание, мое оригинальное (очень старое) предложение было использовать
map
(что намного медленнее):источник
.map
чтобы использовать существующие серии вместоlambda
? Я пытаюсьdf1['e'] = df1['a'].map(lambda x: e)
или,df1['e'] = df1['a'].map(e)
но это не то, что мне нужно. (Я новичок в Pyhon, и ваш предыдущий ответ мне уже помог)e
серия, тогда вам не нужно использоватьmap
, используйтеdf['e']=e
(ответ @joaquins).Супер простое назначение столбцов
Фрейм данных Pandas реализован в виде упорядоченного набора столбцов.
Это означает, что
__getitem__
[]
можно использовать не только для получения определенного столбца, но__setitem__
[] =
и для назначения нового столбца.Например, к этому фрейму данных можно добавить столбец, просто используя метод
[]
доступаОбратите внимание, что это работает, даже если индекс датафрейма выключен.
[] = это путь, но будьте осторожны!
Однако, если у вас есть
pd.Series
и вы попытаетесь назначить его на фрейм данных, где индексы отключены, вы столкнетесь с проблемами. Смотрите пример:Это связано с тем, что
pd.Series
по умолчанию индекс имеет нумерацию от 0 до n. И[] =
метод панд пытается быть "умным"Что на самом деле происходит.
Когда вы используете
[] =
метод, pandas спокойно выполняет внешнее соединение или внешнее объединение, используя индекс левого кадра данных и индекс правого ряда.df['column'] = series
Примечание
Это быстро вызывает когнитивный диссонанс, так как
[]=
метод пытается сделать много разных вещей в зависимости от входных данных, и результат не может быть предсказан, если вы просто не знаете, как работает панда. Поэтому я бы посоветовал не использовать[]=
базы кода, но при изучении данных в блокноте это нормально.Обойти проблему
Если у вас есть
pd.Series
и вы хотите, чтобы он был назначен сверху вниз, или если вы кодируете производительный код, и вы не уверены в порядке индекса, стоит того, чтобы его защитить от такого рода проблем.Вы можете понизить
pd.Series
доnp.ndarray
илиlist
, это сделает свое дело.или
Но это не очень явно.
Может прийти какой-нибудь кодер и сказать: «Эй, это выглядит излишним, я просто оптимизирую это».
Явный способ
Установка индекса в
pd.Series
качестве индексаdf
является явным.Или, более реалистично, вы, вероятно,
pd.Series
уже есть в наличии.Теперь можно назначить
Альтернативный способ с
df.reset_index()
Поскольку диссонанс индекса представляет собой проблему, если вы чувствуете, что индекс фрейма данных не должен диктовать что-то, вы можете просто отбросить индекс, это должно быть быстрее, но не очень чисто, поскольку ваша функция теперь, вероятно, выполняет две вещи.
Обратите внимание на
df.assign
Хотя
df.assign
это и делает более четким то, что вы делаете, на самом деле оно имеет те же проблемы, что и выше[]=
Просто следите за тем,
df.assign
чтобы ваша колонка не называласьself
. Это приведет к ошибкам. Этоdf.assign
воняет , так как в функции есть такие артефакты.Вы можете сказать: «Ну, тогда я просто не буду использовать
self
». Но кто знает, как эта функция изменится в будущем, чтобы поддержать новые аргументы. Возможно, имя вашего столбца будет аргументом в новом обновлении панд, что вызовет проблемы с обновлением.источник
[] =
метод, pandas спокойно выполняет внешнее соединение или внешнее объединение ». Это самая важная информация во всей теме. Но не могли бы вы предоставить ссылку на официальную документацию о том, как[]=
работает оператор?Самые простые способы: -
Таким образом, вы избегаете того, что называется цепной индексацией при установке новых значений в объекте pandas. Нажмите здесь, чтобы прочитать дальше .
источник
Если вы хотите установить для всего нового столбца начальное базовое значение (например
None
), вы можете сделать это:df1['e'] = None
Это на самом деле назначило бы тип «объект» для ячейки. Таким образом, позже вы можете размещать сложные типы данных, например списки, в отдельных ячейках.
источник
Я получил ужас
SettingWithCopyWarning
, и это не было исправлено с помощью синтаксиса iloc. Мой DataFrame был создан read_sql из источника ODBC. Используя предложение от lowtech выше, у меня сработало следующее:Это работало нормально, чтобы вставить столбец в конце. Я не знаю, является ли это наиболее эффективным, но мне не нравятся предупреждающие сообщения. Я думаю, что есть лучшее решение, но я не могу найти его, и я думаю, что это зависит от некоторого аспекта индекса.
Примечание . То, что это работает только один раз и выдаст сообщение об ошибке при попытке перезаписать и существующий столбец.
Примечание. Как и выше, с 0.16.0 назначить является лучшим решением. См. Документацию http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.assign.html#pandas.DataFrame.assign Хорошо работает для типа потока данных, где вы не перезаписываете свои промежуточные значения.
источник
list_of_e
соответствующими данными.df['e'] = list_of_e
источник
tolist()
команда может быть полезна.Если столбец, который вы пытаетесь добавить, является переменной серии, просто:
Это хорошо работает, даже если вы заменяете существующий столбец. Просто введите имя нового столбца, то же самое, что столбец, который вы хотите заменить. Он просто перезапишет данные существующего столбца данными новой серии.
источник
Если фрейм данных и объект Series имеют одинаковый индекс ,
pandas.concat
здесь также работает:Если они не имеют одинаковый индекс:
источник
Защищенное:
Пример:
источник
Позвольте мне добавить, что, как и для hum3 ,
.loc
это не решило проблему,SettingWithCopyWarning
и мне пришлось прибегнуть к нейdf.insert()
. В моем случае ложное срабатывание было сгенерировано "фиктивной" цепной индексациейdict['a']['e']
, где'e'
новый столбец иdict['a']
DataFrame из словаря.Также обратите внимание, что если вы знаете, что делаете, вы можете переключить предупреждение, используя,
pd.options.mode.chained_assignment = None
а затем использовать одно из других решений, приведенных здесь.источник
чтобы вставить новый столбец в заданном месте (0 <= loc <= количество столбцов) во фрейме данных, просто используйте Dataframe.insert:
Поэтому, если вы хотите добавить столбец e в конце фрейма данных с именем df , вы можете использовать:
ценность может быть Series, целым числом (в этом случае все ячейки заполняются этим одним значением) или структурой, подобной массиву
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.insert.html
источник
Перед назначением нового столбца, если вы проиндексировали данные, вам нужно отсортировать индекс. По крайней мере, в моем случае мне пришлось:
источник
Однако следует отметить, что если вы делаете
фактически это будет левое соединение в df1.index. Поэтому, если вы хотите получить эффект внешнего соединения, моё, вероятно, несовершенное решение - создать фрейм данных со значениями индекса, охватывающими всю совокупность ваших данных, а затем использовать приведенный выше код. Например,
источник
Я искал общий способ добавления столбца
numpy.nan
s к кадру данных, не получая глупостиSettingWithCopyWarning
.Из следующего:
numpy
массива NaNs в строкеЯ придумал это:
источник
Чтобы добавить новый столбец 'e' в существующий фрейм данных
источник
Ради полноты - еще одно решение с использованием DataFrame.eval () :
Данные:
Решение:
источник
Создать пустой столбец
источник
Вот что я сделал ... Но я довольно новичок в пандах и вообще в Python, так что никаких обещаний.
источник
Если вы получили
SettingWithCopyWarning
, простое решение - скопировать DataFrame, к которому вы пытаетесь добавить столбец.источник