Добавить столбец с постоянным значением в кадр данных pandas

Учитывая 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

Ответ 1

Причина, по которой помещается 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

Ответ 2

Супер просто: прямое назначение

Для модификации на месте выполните прямое назначение. Это назначение транслируется пандами для каждого ряда.

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

Создание копии: DataFrame.assign

Если вам нужна копия, используйте 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

Ответ 3

Вот еще один вкладыш, использующий лямбды (создать столбец с постоянным значением = 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