我在Pandas中创建或分配新列时发现了一些意外行为。当我过滤或排序pd.DataFrame(从而混合索引(,然后从pd.Series创建一个新列时,Pandas会重新排序序列以映射到DataFrame索引。例如:
df = pd.DataFrame({'a': ['alpha', 'beta', 'gamma']},
index=[2, 0, 1])
df['b'] = pd.Series(['alpha', 'beta', 'gamma'])
索引 | a | b |
---|---|---|
2 | α | γ |
0 | β | α |
1 | γ | β//tr>
如果您不想在panda和numpy之间转换数据类型(例如,使用日期时间(,您可以在分配给列之前将Series的索引设置为与DataFrame的索引相同:
使用
.set_axis()
原始系列将保留其索引-默认情况下,此操作是而不是:
ser = pd.Series(['alpha', 'beta', 'gamma'])
df['b'] = ser.set_axis(df.index)
- 或者您可以更改原始系列的索引:
ser.index = df.index # ser.set_axis(df.index, inplace=True) # alternative
df['b'] = ser
或:
使用numpy数组而不是Series。它没有索引,所以没有什么可以对齐的。
任何系列都可以通过.to_numpy()
:转换为numpy数组
df['b'] = ser.to_numpy()
也可以使用任何其他类似的数组,例如列表。
我不知道这是否是故意的,但新的列分配是基于索引的,你需要维护旧的索引吗?
如果答案是否定的,您可以在添加新列之前简单地重置索引
df.reset_index(drop=True)
在您的示例中,我看不出有任何理由将其作为一个新系列?(即使有东西剥离了索引,比如转换为列表(
df = pd.DataFrame({'num': [1, 2, 3]}, index=[2, 0, 1])
.assign(num_times_two=lambda x: list(x['num']*2))
print(df)
输出:
num num_times_two
2 1 2
0 2 4
1 3 6