通过带有 if 语句的函数对数据框中的数字执行操作
Perform operations on numbers in dataframe through a function with an if statement
我一直在与 pandas 合作,通过定义的函数对数据集进行分析和执行一些冗长的操作(为了方便,也因为我在不涉及 pandas 的操作中使用了相同的函数)。我正在尝试使用 if 和 else 语句根据哪个数字更大来执行一些操作。
我没能在其他答案中找到解决方法。这是我尝试执行的逻辑操作类型的简短示例:
import pandas as pd
df = pd.DataFrame({"A": [177,166,155,125,146,149,192,160,111,85],
"B": [26.2,27,26.8,23.4,23.3,17.5,26.4,25.7,18.9,15.8],
"C": [9.2,99.1,29.3,8.6,8,7.2,10,39.4,47.25,4.5,]})
x = 'A'
y = 'B'
z = 'C'
def test(a,b,c):
h = a*b/c
return h
df['D'] = test(df[x],df[y],df[z])
到目前为止,函数一直在为我工作:
print(df['D'])
0 504.065217
1 45.227043
2 141.774744
3 340.116279
4 425.225000
5 362.152778
6 506.880000
7 104.365482
8 44.400000
9 298.444444
Name: D, dtype: float64
我希望让这样的操作正常工作:
def test2(a,b,c):
if a > b:
return a*c
else:
return b*c
df['E'] = test2(df[x],df[y],df[z])
print(df['E'])
我收到了明显的错误:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
你需要:
df['E'] = df.apply(lambda x: test2(x['A'], x['B'], x['C']) ,1)
输出:
A B C E
0 177 26.2 9.20 1628.40
1 166 27.0 99.10 16450.60
2 155 26.8 29.30 4541.50
3 125 23.4 8.60 1075.00
4 146 23.3 8.00 1168.00
5 149 17.5 7.20 1072.80
6 192 26.4 10.00 1920.00
7 160 25.7 39.40 6304.00
8 111 18.9 47.25 5244.75
9 85 15.8 4.50 382.50
另一个解决方案是使用 np.where
:
df["E"] = np.where(df.A > df.B, df.A*df.C, df.B*df.C)
print(df)
# A B C E
# 0 177 26.2 9.20 1628.40
# 1 166 27.0 99.10 16450.60
# 2 155 26.8 29.30 4541.50
# 3 125 23.4 8.60 1075.00
# 4 146 23.3 8.00 1168.00
# 5 149 17.5 7.20 1072.80
# 6 192 26.4 10.00 1920.00
# 7 160 25.7 39.40 6304.00
# 8 111 18.9 47.25 5244.75
# 9 85 15.8 4.50 382.50
在这种情况下,np.where
似乎比 apply
更有效率(快 40 倍)。这里的效率结果:
import timeit
def numpy_where(df):
def func():
df["E"] = np.where(df.A > df.B, df.A*df.C, df.B*df.C)
return func
def pandas_apply(df):
def test2(a, b, c):
if a > b:
return a*c
return b*c
def func():
df["E"] = df.apply(lambda x: test2(x['A'], x['B'], x['C']), 1)
return func
t = timeit.Timer(numpy_where(df))
print(t.timeit(100))
# 0.0711541
t = timeit.Timer(pandas_apply(df))
print(t.timeit(100))
# 2.8589093
#try this (still using a function):
def test2(row):
if row['A'] > row['B']:
return row['A'] * row['C']
else:
return row['B']*row['C']
df['E'] = df.apply(test2, axis=1)
A B C D E
0 177 26.2 9.20 504.065217 1628.40
1 166 27.0 99.10 45.227043 16450.60
2 155 26.8 29.30 141.774744 4541.50
3 125 23.4 8.60 340.116279 1075.00
4 146 23.3 8.00 425.225000 1168.00
5 149 17.5 7.20 362.152778 1072.80
6 192 26.4 10.00 506.880000 1920.00
7 160 25.7 39.40 104.365482 6304.00
8 111 18.9 47.25 44.400000 5244.75
9 85 15.8 4.50 298.444444 382.50
但使用 np.where 是最好的解决方案。
我一直在与 pandas 合作,通过定义的函数对数据集进行分析和执行一些冗长的操作(为了方便,也因为我在不涉及 pandas 的操作中使用了相同的函数)。我正在尝试使用 if 和 else 语句根据哪个数字更大来执行一些操作。
我没能在其他答案中找到解决方法。这是我尝试执行的逻辑操作类型的简短示例:
import pandas as pd
df = pd.DataFrame({"A": [177,166,155,125,146,149,192,160,111,85],
"B": [26.2,27,26.8,23.4,23.3,17.5,26.4,25.7,18.9,15.8],
"C": [9.2,99.1,29.3,8.6,8,7.2,10,39.4,47.25,4.5,]})
x = 'A'
y = 'B'
z = 'C'
def test(a,b,c):
h = a*b/c
return h
df['D'] = test(df[x],df[y],df[z])
到目前为止,函数一直在为我工作:
print(df['D'])
0 504.065217
1 45.227043
2 141.774744
3 340.116279
4 425.225000
5 362.152778
6 506.880000
7 104.365482
8 44.400000
9 298.444444
Name: D, dtype: float64
我希望让这样的操作正常工作:
def test2(a,b,c):
if a > b:
return a*c
else:
return b*c
df['E'] = test2(df[x],df[y],df[z])
print(df['E'])
我收到了明显的错误:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
你需要:
df['E'] = df.apply(lambda x: test2(x['A'], x['B'], x['C']) ,1)
输出:
A B C E
0 177 26.2 9.20 1628.40
1 166 27.0 99.10 16450.60
2 155 26.8 29.30 4541.50
3 125 23.4 8.60 1075.00
4 146 23.3 8.00 1168.00
5 149 17.5 7.20 1072.80
6 192 26.4 10.00 1920.00
7 160 25.7 39.40 6304.00
8 111 18.9 47.25 5244.75
9 85 15.8 4.50 382.50
另一个解决方案是使用 np.where
:
df["E"] = np.where(df.A > df.B, df.A*df.C, df.B*df.C)
print(df)
# A B C E
# 0 177 26.2 9.20 1628.40
# 1 166 27.0 99.10 16450.60
# 2 155 26.8 29.30 4541.50
# 3 125 23.4 8.60 1075.00
# 4 146 23.3 8.00 1168.00
# 5 149 17.5 7.20 1072.80
# 6 192 26.4 10.00 1920.00
# 7 160 25.7 39.40 6304.00
# 8 111 18.9 47.25 5244.75
# 9 85 15.8 4.50 382.50
在这种情况下,np.where
似乎比 apply
更有效率(快 40 倍)。这里的效率结果:
import timeit
def numpy_where(df):
def func():
df["E"] = np.where(df.A > df.B, df.A*df.C, df.B*df.C)
return func
def pandas_apply(df):
def test2(a, b, c):
if a > b:
return a*c
return b*c
def func():
df["E"] = df.apply(lambda x: test2(x['A'], x['B'], x['C']), 1)
return func
t = timeit.Timer(numpy_where(df))
print(t.timeit(100))
# 0.0711541
t = timeit.Timer(pandas_apply(df))
print(t.timeit(100))
# 2.8589093
#try this (still using a function):
def test2(row):
if row['A'] > row['B']:
return row['A'] * row['C']
else:
return row['B']*row['C']
df['E'] = df.apply(test2, axis=1)
A B C D E
0 177 26.2 9.20 504.065217 1628.40
1 166 27.0 99.10 45.227043 16450.60
2 155 26.8 29.30 141.774744 4541.50
3 125 23.4 8.60 340.116279 1075.00
4 146 23.3 8.00 425.225000 1168.00
5 149 17.5 7.20 362.152778 1072.80
6 192 26.4 10.00 506.880000 1920.00
7 160 25.7 39.40 104.365482 6304.00
8 111 18.9 47.25 44.400000 5244.75
9 85 15.8 4.50 298.444444 382.50
但使用 np.where 是最好的解决方案。