[英]Setting the values of a pandas df column based on ranges of values of another df column
我有一个看起来像这样的df:
df = pd.DataFrame({'a':[-3,-2,-1,0,1,2,3], 'b': [1,2,3,4,5,6,7]})
我想创建一个列'c',它查看'a'的值以确定对'b'执行什么操作并将其显示在新列'c'中。
我有一个使用 iterrow 的解决方案,但是,我的真实 df 很大并且 iterrows 效率低下。
我想做的是以矢量化形式执行此操作。 我的“慢”解决方案是:
df['c'] = 0
for index, row in df.iterrows():
if row['a'] <=-2:
row['c'] = row['b']*np.sqrt(row[b]*row[a])
if row['a'] > -2 and row['a'] < 2:
row['c'] = np.log(row['b'])
if row['a'] >= 2:
row['c'] = row['b']**3
使用np.select 。 这是一个矢量化操作。
conditions = [
df['a'] <= -2,
(df['a'] > -2) & (df['a'] < 2),
df['a'] >= 2
]
values = [
df['b'] * np.sqrt(df['b'] * df['a'])
np.log(df['b']),
df['b']**3
]
df['c'] = np.select(conditions, values, default=0)
您可以在 pandas(指定轴 = 1)和 lambda function 中使用 and.apply 来完成工作。 不知道速度是否正常。 看这个例子:
import pandas as pd
import numpy as np
df = pd.DataFrame({'a':[-3,-2,-1,0,1,2,3], 'b': [1,2,3,4,5,6,7]})
def func(a_, b_):
if a_<=-2:
return b_*(b_*a_)**0.5
elif a_<2:
return np.log(b_)
else:
return b_**3.
df['c'] = df[['a','b']].apply(lambda x: func(x[0], x[1]), axis=1)
我们可以使用pd.cut
df.b.pow(pd.cut(df.a,[-np.Inf,-2,2,np.Inf],labels=[2,1,3]).astype(int))
Out[193]:
0 1
1 4
2 3
3 4
4 5
5 6
6 343
dtype: int64
df['c']=df.b.pow(pd.cut(df.a,[-np.Inf,-2,2,np.Inf],labels=[2,1,3]).astype(int))
df['c'] = df.apply(lambda x: my_func(x), 1)
def my_func(x):
if x['a'] <= -2:
return x['b']*np.sqrt(x[b]*x[a])
# write other conditions as needed
The df.apply
function iterates over each row of the dataframe and applies the function passed(ie lambda function
). 第二个参数是设置为 1 的轴,这意味着它将遍历行并且行值将被传递到lambda
function。 默认为 0,在这种情况下它将遍历列。 最后,您需要返回一个值,该值将设置为列“c”值。
一种方法是按条件索引,然后仅对这些行进行操作。 像这样的东西:
df['c'] = np.nan
indices = [
df['a'] <= -2,
(df['a'] > -2) & (df['a'] < 2),
df['a'] >= 2
]
ops = [
lambda x: x['b'] * np.sqrt(x['b'] * x['a']),
lambda x: np.log(x['b']),
lambda x: x['b']**3
]
for ix, op in zip(indices, ops):
df.loc[ix, 'c'] = op(df)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.