numpy 如何用“np.where”填充 Dataframe 的两列?

nr9pn0ug  于 2022-11-24  发布在  其他
关注(0)|答案(4)|浏览(201)

我尝试在第三列上按条件设置2列。我可以在另一列上设置1列条件,也可以在单个条件值上设置2列,但当我尝试在一列上按条件设置2列时,失败了。
下面是代码示例:

import pandas as pd
import numpy as np
AAA = {"column A": [1, 1, 1, 2, 2, 2, 3, 3, 3]}
df = pd.DataFrame(AAA)

如果我叫:

df["column B"], df["column C"] = np.where(True ,['4', '8'],['NaN', 'NaN'])

我得到:

df
   column A column B column C
0         1        4        8
1         1        4        8
2         1        4        8
3         2        4        8
4         2        4        8
5         2        4        8
6         3        4        8
7         3        4        8
8         3        4        8

所以我知道我可以根据条件填充两列。
如果我叫:

df["column B"] = np.where( df["column A"] == 2 ,['4'],['NaN'])

我得到:

column A column B column C
0         1      NaN        8
1         1      NaN        8
2         1      NaN        8
3         2        4        8
4         2        4        8
5         2        4        8
6         3      NaN        8
7         3      NaN        8
8         3      NaN        8

所以我知道我可以根据列上的条件填充。(我假设这被视为布尔数组)
但是,如果我调用:

df["column B"], df["column C"] = np.where( df["column A"] == 2 ,['4', '8'],['NaN', 'NaN'])

我期望得到

column A column B column C
0         1      NaN        NaN        
1         1      NaN        NaN        
2         1      NaN        NaN        
3         2        4        8
4         2        4        8
5         2        4        8
6         3      NaN        NaN        
7         3      NaN        NaN        
8         3      NaN        NaN

但实际上我得到的是

Traceback (most recent call last):
 ... pydev\_pydevd_bundle\pydevd_exec2.py", line 3, in Exec
    exec(exp, global_vars, local_vars)
  File "<string>", line 2, in <module>
  File "<__array_function__ internals>", line 6, in where
ValueError: operands could not be broadcast together with shapes (9,) (2,) (2,)

我不想使用2个单独的调用,因为我需要的 Dataframe 非常大。

nxowjjhe

nxowjjhe1#

使用loc索引器并给予值

df.loc[df['column A'] == 2, ['column B', 'column C']] = [4, 8]

输出(df):

column A    column B    column C
0   1           NaN         NaN
1   1           NaN         NaN
2   1           NaN         NaN
3   2           4.0         8.0
4   2           4.0         8.0
5   2           4.0         8.0
6   3           NaN         NaN
7   3           NaN         NaN
8   3           NaN         NaN
iqxoj9l9

iqxoj9l92#

也许你可以在np.where之外循环:

df["column B"], df["column C"] = [np.where( df["column A"] == 2 ,true_val,'NaN') for true_val in ['4','8']]

print(df)
# column A column B column C
# 0         1      NaN      NaN
# 1         1      NaN      NaN
# 2         1      NaN      NaN
# 3         2        4        8
# 4         2        4        8
# 5         2        4        8
# 6         3      NaN      NaN
# 7         3      NaN      NaN
# 8         3      NaN      NaN
6yt4nkrj

6yt4nkrj3#

你就快到了!这只是一个“广播”的问题。
你可以使用其他人提出的任何问题,或者使用相同的概念,但稍微改变输入。
就像这样:

# Reshape the condition, then transpose the output.
df["column B"], df["column C"] = np.where( np.array(df["column A"] == 2).reshape(-1,1) ,['4', '8'],['NaN', 'NaN']).T

还是这样:

# Or just reshape the lists
df["column B"], df["column C"] = np.where( df["column A"] == 2 ,np.array(['4', '8']).reshape(-1,1),np.array(['NaN', 'NaN']).reshape(-1,1))

输出量:

column A    column B    column C
0   1   NaN NaN
1   1   NaN NaN
2   1   NaN NaN
3   2   4   8
4   2   4   8
5   2   4   8
6   3   NaN NaN
7   3   NaN NaN
8   3   NaN NaN

您可以查看有关广播的numpy文档来了解以下内容:https://numpy.org/doc/stable/user/basics.broadcasting.html

kb5ga3dv

kb5ga3dv4#

这里有一个方法。虽然它不是最优雅的代码-它应该帮助你理解需要什么。

import pandas as pd
import numpy as np

AAA={"column A": [1, 1, 1, 2, 2, 2, 3, 3, 3]}
df = pd.DataFrame(AAA)

col_length = len(df['column A'])
fours = np.repeat(4, col_length, axis =0)
eights = np.repeat(8, col_length, axis =0)
empties = np.repeat(np.nan, col_length, axis =0)

df["column B"], df["column C"] = np.where( df["column A"] == 2 ,[fours, eights], [empties, empties])
print(df)

输出:

column A  column B  column C
0         1       NaN       NaN
1         1       NaN       NaN
2         1       NaN       NaN
3         2       4.0       8.0
4         2       4.0       8.0
5         2       4.0       8.0
6         3       NaN       NaN
7         3       NaN       NaN
8         3       NaN       NaN

相关问题