Учитывая DataFrame:
np.random.seed(0)
df = pd.DataFrame(np.random.randn(3, 3), columns=list('ABC'), index=[1, 2, 3])
df
A B C
1 1.764052 0.400157 0.978738
2 2.240893 1.867558 -0.977278
3 0.950088 -0.151357 -0.103219
Каков самый простой способ добавить новый столбец, содержащий постоянное значение, например 0?
A B C new
1 1.764052 0.400157 0.978738 0
2 2.240893 1.867558 -0.977278 0
3 0.950088 -0.151357 -0.103219 0
Это мое решение, но я не знаю, почему при этом NaN помещается в «новый» столбец?
df['new'] = pd.Series([0 for x in range(len(df.index))])
A B C new
1 1.764052 0.400157 0.978738 0.0
2 2.240893 1.867558 -0.977278 0.0
3 0.950088 -0.151357 -0.103219 NaN
df['new'] = pd.Series([0 for x in range(len(df.index))], index=df.index)
.[0] * len(df.index)
df['new'] = 0
Ответы:
Причина, по которой это помещается
NaN
в столбец, заключается в том, чтоdf.index
иIndex
ваш правый объект разные. @zach показывает, как правильно назначить новый столбец с нулями. В общем,pandas
старается как можно больше выравнивать индексы. Одним из недостатков является то, что когда индексы не выровнены, вы попадаетеNaN
туда, где они не выровнены. Поиграйте сreindex
иalign
методами , чтобы получить некоторую интуицию для выравнивания работы с объектами , которые имеют частично, полностью, а не выровнены-все выровненные показатели. Например, вот какDataFrame.align()
работает с частично выровненными индексами:In [7]: from pandas import DataFrame In [8]: from numpy.random import randint In [9]: df = DataFrame({'a': randint(3, size=10)}) In [10]: In [10]: df Out[10]: a 0 0 1 2 2 0 3 1 4 0 5 0 6 0 7 0 8 0 9 0 In [11]: s = df.a[:5] In [12]: dfa, sa = df.align(s, axis=0) In [13]: dfa Out[13]: a 0 0 1 2 2 0 3 1 4 0 5 0 6 0 7 0 8 0 9 0 In [14]: sa Out[14]: 0 0 1 2 2 0 3 1 4 0 5 NaN 6 NaN 7 NaN 8 NaN 9 NaN Name: a, dtype: float64
источник
Супер простое назначение на месте:
df['new'] = 0
Для модификации на месте выполните прямое назначение. Это задание транслируется пандами для каждой строки.
df = pd.DataFrame('x', index=range(4), columns=list('ABC')) df A B C 0 x x x 1 x x x 2 x x x 3 x x x
df['new'] = 'y' # Same as, # df.loc[:, 'new'] = 'y' df A B C new 0 x x x y 1 x x x y 2 x x x y 3 x x x y
Примечание для столбцов объекта
Если вы хотите добавить столбец с пустыми списками, вот мой совет:
object
столбцы - плохие новости с точки зрения производительности. Подумайте, как структурированы ваши данные.Если вам необходимо сохранить столбец списков, не копируйте одну и ту же ссылку несколько раз.
# Wrong df['new'] = [[]] * len(df) # Right df['new'] = [[] for _ in range(len(df))]
Создание копии:
df.assign(new=0)
Если вам нужна копия, используйте
DataFrame.assign
:df.assign(new='y') A B C new 0 x x x y 1 x x x y 2 x x x y 3 x x x y
И, если вам нужно назначить несколько таких столбцов с одинаковым значением, это так же просто, как,
c = ['new1', 'new2', ...] df.assign(**dict.fromkeys(c, 'y')) A B C new1 new2 0 x x x y y 1 x x x y y 2 x x x y y 3 x x x y y
Назначение нескольких столбцов
Наконец, если вам нужно назначить несколько столбцов с разными значениями, вы можете использовать
assign
словарь.c = {'new1': 'w', 'new2': 'y', 'new3': 'z'} df.assign(**c) A B C new1 new2 new3 0 x x x w y z 1 x x x w y z 2 x x x w y z 3 x x x w y z
источник
С современными пандами вы можете просто:
df['new'] = 0
источник
Вот еще один лайнер с использованием лямбда-выражений (создать столбец с постоянным значением = 10)
df['newCol'] = df.apply(lambda x: 10, axis=1)
перед
df A B C 1 1.764052 0.400157 0.978738 2 2.240893 1.867558 -0.977278 3 0.950088 -0.151357 -0.103219
после
df A B C newCol 1 1.764052 0.400157 0.978738 10 2 2.240893 1.867558 -0.977278 10 3 0.950088 -0.151357 -0.103219 10
источник
df['newCol'] = 10
также является однострочным (и быстрее). В чем преимущество использования здесь?df['new'] = [[] for _ in range(len(df))]