给定DataFrame
import pandas as pd
df = pd.DataFrame({
'transformed': ['left', 'right', 'left', 'right'],
'left_f': [1, 2, 3, 4],
'right_f': [10, 20, 30, 40],
'left_t': [-1, -2, -3, -4],
'right_t': [-10, -20, -30, -40],
})
Run Code Online (Sandbox Code Playgroud)
我想创建两个新列,从中选择一个,left_*或right_*根据其内容进行选择transformed:
df['transformed_f'] = df['right_f'].where(
df['transformed'] == 'right',
df['left_f']
)
df['transformed_t'] = df['right_t'].where(
df['transformed'] == 'right',
df['left_t']
)
Run Code Online (Sandbox Code Playgroud)
我得到了预期的结果
df
# transformed left_f right_f left_t right_t transformed_f transformed_t
# 0 left 1 10 -1 -10 1 -1
# 1 right 2 20 -2 -20 20 -20
# 2 left 3 30 -3 -30 3 -3
# 3 right 4 40 -4 -40 40 -40
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试在一个操作中执行此操作时,会得到包含NaN值的意外结果
df[['transformed_f', 'transformed_t']] = df[['right_f', 'right_t']].where(
df['transformed'] == 'right',
df[['left_f', 'left_t']]
)
df
# transformed left_f right_f left_t right_t transformed_f transformed_t
# 0 left 1 10 -1 -10 NaN NaN
# 1 right 2 20 -2 -20 20.0 -20.0
# 2 left 3 30 -3 -30 NaN NaN
# 3 right 4 40 -4 -40 40.0 -40.0
Run Code Online (Sandbox Code Playgroud)
有没有办法df.where()一次在多个列上使用?
您很接近,只需添加.valuesor.to_numpy()与切片即可使其成为NDarray:
根据文档:
\n\n\n\n\nother :标量、NDFrame 或可调用\n cond 为 False 的条目将替换为 other 中的相应值。如果 other 可调用,则在 NDFrame 上计算并应返回标量或 NDFrame。可调用不得更改输入 NDFrame (尽管 pandas 不会检查它\xe2\x80\x99t)。
\n
因此,当您直接输入数据帧的切片时,索引(列名称)不匹配,因此它不会更新 df,当您传递 时.values,它会忽略索引并添加值。
df[['transformed_f', 'transformed_t']]=(df[['right_f', 'right_t']].\n where(df['transformed'] == 'right',df[['left_f', 'left_t']].values))\nprint(df)\nRun Code Online (Sandbox Code Playgroud)\n\n transformed left_f right_f left_t right_t transformed_f transformed_t\n0 left 1 10 -1 -10 1 -1\n1 right 2 20 -2 -20 20 -20\n2 left 3 30 -3 -30 3 -3\n3 right 4 40 -4 -40 40 -40\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
93 次 |
| 最近记录: |