我创建了一个 pandas 数据框,我的逻辑是如果“a”列的值为 yes,“b”列的值为 0,则生成 1,15 之间的随机数。我正在尝试使用下面的 lamda 函数,但我似乎遇到了错误
df = pd.DataFrame({'a': ['Yes', 'No', 'Yes','Yes'], 'b': [1, 0, 0,0]})
print(df)
df['b'].apply(lambda x: random.randint(1,15) if x.a == 'Yes' and x ==0 else x)
Input
a b
0 Yes 1
1 No 0
2 Yes 0
3 Yes 0
My expectation is
a b
0 Yes 1
1 No 0
2 Yes 12
3 Yes 5
您遇到的错误是因为在 lambda 函数中,
x
代表 'b'
列中的每个元素,它是一个整数。由于 x
是一个整数,因此它没有属性“a”。当您尝试访问 x.a
时,Python 会引发 AttributeError
,因为整数没有像 DataFrame 行那样的属性。
要解决此问题,您需要访问每行的
'a'
和'b'
两列。有几种方法可以做到这一点:
1) 在 DataFrame 上跨行使用
apply()
(axis=1):
将函数应用于 DataFrame 的每一行,允许您访问多列。
df['b'] = df.apply(
lambda row: random.randint(1, 15) if row['a'] == 'Yes' and row['b'] == 0 else row['b'],
axis=1
)
2)使用布尔索引: 为满足条件的行创建布尔掩码并直接分配随机数。
import numpy as np
mask = (df['a'] == 'Yes') & (df['b'] == 0)
df.loc[mask, 'b'] = np.random.randint(1, 16, size=mask.sum())
3)使用where()方法:
df['b'] = df['b'].where(~((df['a'] == 'Yes') & (df['b'] == 0)), other=np.random.randint(1, 16, size=len(df)))
我现在给你一个完整的例子。我认为这会很有用,我在论坛上过去的搜索中也发现了类似的结果。
import pandas as pd
import random
import numpy as np
df = pd.DataFrame({'a': ['Yes', 'No', 'Yes', 'Yes'], 'b': [1, 0, 0, 0]})
print("Original DataFrame:")
print(df)
# Method 1: Using apply() on the DataFrame
df['b'] = df.apply(
lambda row: random.randint(1, 15) if row['a'] == 'Yes' and row['b'] == 0 else row['b'],
axis=1
)
print("\nDataFrame after applying random numbers with apply():")
print(df)
df = pd.DataFrame({'a': ['Yes', 'No', 'Yes', 'Yes'], 'b': [1, 0, 0, 0]})
# Method 2: Using Boolean indexing
mask = (df['a'] == 'Yes') & (df['b'] == 0)
df.loc[mask, 'b'] = np.random.randint(1, 16, size=mask.sum())
print("\nDataFrame after applying random numbers with Boolean indexing:")
print(df)
使用 np.where
import numpy as np
cond = df['a'].eq('Yes') & df['b'].eq(0)
df['b'] = np.where(cond, np.random.randint(1, 16, len(df)), df['b'])
df:
a b
0 Yes 1
1 No 0
2 Yes 12
3 Yes 14