向熊猫数据框中添加常值列

给定一个数据框架:

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
267082 次浏览

之所以将 NaN放入列中,是因为右侧对象的 df.indexIndex是不同的。@ zach 显示了分配新的零列的正确方法。一般来说,pandas尝试尽可能多地对索引进行对齐。一个缺点是,当指数没有对齐时,无论它们在哪里对齐,都会得到 NaN。使用 reindexalign方法可以获得一些直觉,以便对具有部分、完全和不对齐索引的对象进行对齐。例如,以下是 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))]
    

Generating a copy: df.assign(new=0)

If you need a copy instead, use 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

下面是使用 lambdas 的另一行程序(创建值为常数 = 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['new'] = 0