我正在尝试使用.where pandas数据帧方法,只有我有两种以上的可能性(即我有if,elif,否则代替默认行为,否则)
请考虑以下数据框:
a1 = np.random.rand(7,2)
a2 = np.random.randint(0,3,(7,1))
grid = np.append(a1, a2, axis=1)
df = pd.DataFrame(grid)
我试过
def test(x):
if x[2] == 0:
return 5
if x[2]==1:
return 10
if x[2] ==2:
return 50
df.where(test)
但是我收到错误消息“系列的真值是模棱两可的”。我怀疑这是正确的方向,但我对如何实现它感到困惑。文档说如果条件是可调用的,则输入被认为是完整的df。然而,即便如此,它似乎将x[2]
视为整个第2列。是否无法实现该任务的向量化操作?是否只能逐行迭代,无论是使用iterrows还是应用?
这是一个在论坛上要清楚的玩具示例,我不是想在我的现实生活中解决一个简单的.map问题。请保持“测试”功能作为一个单独的功能,如果你回答需要通过,因为这是我的困难所在。
答案 0 :(得分:2)
np.random.seed(100)
a1 = np.random.rand(7,2)
a2 = np.random.randint(0,3,(7,1))
grid = np.append(a1, a2, axis=1)
df = pd.DataFrame(grid)
print (df)
0 1 2
0 0.543405 0.278369 2.0
1 0.424518 0.844776 2.0
2 0.004719 0.121569 0.0
3 0.670749 0.825853 0.0
4 0.136707 0.575093 1.0
5 0.891322 0.209202 1.0
6 0.185328 0.108377 1.0
map
的解决方案:
d = {0:5,1:10,2:50}
df['d'] = df[2].map(d)
print (df)
0 1 2 d
0 0.543405 0.278369 2.0 50
1 0.424518 0.844776 2.0 50
2 0.004719 0.121569 0.0 5
3 0.670749 0.825853 0.0 5
4 0.136707 0.575093 1.0 10
5 0.891322 0.209202 1.0 10
6 0.185328 0.108377 1.0 10
numpy.where
的另一个解决方案:
df['d'] = np.where(df[2] == 0, 5,
np.where(df[2]== 1, 10, 50))
print (df)
0 1 2 d
0 0.543405 0.278369 2.0 50
1 0.424518 0.844776 2.0 50
2 0.004719 0.121569 0.0 5
3 0.670749 0.825853 0.0 5
4 0.136707 0.575093 1.0 10
5 0.891322 0.209202 1.0 10
6 0.185328 0.108377 1.0 10
编辑:
对于单独的功能,可以使用带有参数axis=1
的{{3}}来df
处理rows
:
def test(x):
#print (x)
if x[2] == 0:
return 5
if x[2]==1:
return 10
if x[2] ==2:
return 50
df['d'] = df.apply(test, axis=1)
print (df)
0 1 2 d
0 0.543405 0.278369 2.0 50
1 0.424518 0.844776 2.0 50
2 0.004719 0.121569 0.0 5
3 0.670749 0.825853 0.0 5
4 0.136707 0.575093 1.0 10
5 0.891322 0.209202 1.0 10
6 0.185328 0.108377 1.0 10
但如果需要功能:
def test(x):
return np.where(x == 0, 5, np.where(x== 1, 10, 50))
print (test(df[2]))
[50 50 5 5 10 10 10]