这是使用panda根据其他列中的条件更新列的有效方法吗



这是使用panda根据其他列中的条件更新列的有效方法吗?我希望推广一个将移动高斯值的更新函数,我在使用lambda时遇到了困难,因为有多个列可能是条件。同样地,应用程序也有问题,因为我无法使变量达到它想要的形式,尽管老实说,我本可以在这方面花更多的时间。

问题说明:我应该如何处理基于另一列中的值更新大熊猫数据帧的问题,以便在可接受的速度参数内运行其中的许多函数?请给出一个完整的例子,如果可能的话,请使用我的"silly_series_generator"来确保我们保持相同的问题案例。谢谢

import random
import pandas

def silly_series_generator():
# requires import of random and pandas
ret = []
ret.append(r.choice(['X', 'Y', 'Z']))
for i in range(9):
ret.append(random.gauss(0,1))
return pandas.Series(ret, list("ABCDEFGHIJ"))

def silly_update(df, condition_col, condition_value, target_col, mean, sd = .1):
# requires import of random and pandas
effected_cells = df[condition_col] == condition_value[0]
x = df[effected_cells][target_col] + r.gauss(mean, sd)
df[target_col].update(x)
return df

def run_test():
# requires import of random and pandas
# requires functions: silly_series_generator and silly_update
rows = []
for i in range(50):
rows.append(silly_series_generator())
original_df = pd.DataFrame(rows)
print('original_df',original_df['B'].mean())
updated_df = silly_update(original_df, 'A', 'X', 'B', 1)
print('updated_df', updated_df['B'].mean())
if __name__ == "__main__":
run_test()

我不确定下面的例子是否更快(我确定apply()更慢(,但我会这样做。回顾你的问题-我不确定它是否有足够的不同,可以写出来,但它就在这里。

生成数据

import numpy as np
import pandas as pd
import random
def silly_series_generator():
# requires import of random and pandas
ret = []
ret.append(random.choice(['X', 'Y', 'Z']))
for i in range(9):
ret.append(random.gauss(0,1))
return pd.Series(ret, list("ABCDEFGHIJ"))
rows = []
for i in range(50):
rows.append(silly_series_generator())
df = pd.DataFrame(rows)

使用apply

我认为apply通常是最慢的路由,因为它一次只在一行上运行。不过我还是喜欢它,所以这里有一个例子。我们可以将额外的args与kwargs一起提供给apply()

def update(row, condition_col, condition_value, target_col, mean, sd = .1):
if row[condition_col] == condition_value:
v = row[target_col] + random.gauss(mean, sd)
else:
v = row[target_col]
return v
df['B'] = df.apply(update, axis=1, condition_col='A', condition_value='X', target_col='B', mean=1)

使用遮罩

这基本上就是你所做的——我只是使用了.loc[]而不是.update()。我不确定它是否更快,但这是另一种选择。

mask = df['A'] == 'X'
df.loc[mask, 'B'] = df['B'] + random.gauss(1, 0.1)

使用掩码-每行新的随机值

目前还不清楚您是否希望在每一行中添加相同的随机数。按照我们现在的设置方式,它是添加到所有匹配项中的相同随机数。我们可能希望每个值每次都移动一个不同的随机数。

下面是为每一行生成一个新的随机数的示例。我将留下一些额外的列进行调试。

mask = df['A'] == 'X'
# Generate a random number for each row
# df['r'] = np.random.normal(1, 0.1, size=(df.shape[0],1))
# Only generate the random numbers for the mask locations
df.loc[mask, 'r'] = np.random.normal(1, 0.1, size=(df[mask].shape[0],1))
df.loc[mask, 'Bprime'] =  df['B'] + df['r']

最新更新