在不映射到索引(即不重新排序值)的情况下,能否将pd.Series分配给无序pd.DataFrame中的列



我在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'])
β//tr>
索引ab
2αγ
0βα
1γ

如果您不想在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

最新更新