在我的DataFrame中,我希望将特定列的值剪切为0到100.例如,给定以下内容:
a b
0 10 90
1 20 150
2 30 -30
我想得到:
a b c
0 10 90 90
1 20 150 100
2 30 -30 0
我知道在Pandas中,某些算术运算可以跨列工作。例如,我可以将b
列中的每个数字加倍,如下所示:
>>>df["c"] = df["b"] * 2
>>>df
a b c
0 10 90 180
1 20 150 300
2 30 -30 -60
但是,这对min
和max
等内置函数无效:
>>>df["c"] = min(100, max(0, df["b"]))
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
有没有办法有效地完成我想要的东西?
答案 0 :(得分:7)
您可以使用Series.clip
:
df['c'] = df['b'].clip(0,100)
print (df)
a b c
0 10 90 90
1 20 150 100
2 30 -30 0
答案 1 :(得分:3)
您可以在轴上使用Pandas min功能。然后将其与min / max
组合https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.min.html
例如
df.max(axis=1)
但看起来你想要剪切值而不是min / max。
答案 2 :(得分:0)
numpy
视图。不如clip
那么优雅。
选项1
df.assign(c=np.minimum(np.maximum(df.b.values, 0), 100))
a b c
0 10 90 90
1 20 150 100
2 30 -30 0
选项2
b = df.b.values
df.assign(c=np.where(b > 100, 100, np.where(b < 0, 0, b)))
a b c
0 10 90 90
1 20 150 100
2 30 -30 0
<强>时序强>
以下代码
res.div(res.min(1), 0)
pir1 pir2 jez1
10 30.895514 1.0 75.210427
30 28.611177 1.0 49.913498
100 20.658307 1.0 50.823106
300 19.842134 1.0 39.162901
1000 14.078159 1.0 25.148937
3000 8.767133 1.0 15.066847
10000 4.377849 1.0 8.849138
30000 2.634263 1.0 4.653956
res = pd.DataFrame(
index=[10, 30, 100, 300, 1000, 3000, 10000, 30000],
columns=['pir1', 'pir2', 'jez1'],
dtype=float
)
jez1 = lambda d: d.assign(c=df.b.clip(0, 1))
pir1 = lambda d: d.assign(c=np.minimum(np.maximum(d.b.values, 0), 100))
pir2 = lambda d: (lambda b: np.where(b > 100, 100, np.where(b < 0, 0, b)))(d.b.values)
for i in res.index:
d = pd.concat([df] * i, ignore_index=True)
for j in res.columns:
stmt = '{}(d)'.format(j)
setp = 'from __main__ import d, {}'.format(j)
res.at[i, j] = timeit(stmt, setp, number=10)
res.plot(loglog=True)