Python 如何在dataframe中创建一个新列,它将是其他列和条件的函数,而无需使用for循环迭代行?

Python 如何在dataframe中创建一个新列,它将是其他列和条件的函数,而无需使用for循环迭代行?,python,pandas,Python,Pandas,我有一个相对较大的数据框(8737行和16列,包括所有变量类型、字符串、整数、布尔值等),我想根据一个等式和一些条件创建一个新列。基本上,我想迭代一个特定的列,获取它的值,然后在乘法、求和等之后创建一个新值,然后检查它是否满足某些条件(>=或对于循环,无。此(未测试)&不确定值在5到10之间时想要什么 df_测试['S'].iloc[0]=5 测向测试['S']=测向测试['S'].shift()+测向测试['D']*abs(测向测试['C'])*0.5 df_测试['S']=np.其中(df_

我有一个相对较大的数据框(8737行和16列,包括所有变量类型、字符串、整数、布尔值等),我想根据一个等式和一些条件创建一个新列。基本上,我想迭代一个特定的列,获取它的值,然后在乘法、求和等之后创建一个新值,然后检查它是否满足某些条件(>=或<到一个设定值)。如果它满足条件,那么我需要保持计算的输出,否则指定一个固定值

我使用for循环遍历整个数据集,这需要花费大量时间。我是python新手,除了在没有for循环的情况下交替使用现有列之外,在网上找不到任何类似的问题解决方案

假设为了简单起见,我有一个称为df_test的数据帧:

          A         B         C          D    S
0  0.001568  0.321316 -0.269841   3.232037  5.0
1  1.926186 -1.111863 -0.387165   5.541699  NaN
2  2.110923 -0.403940 -0.029895  -9.688968  NaN
3  0.609391  1.697205 -1.827488  -1.273713  NaN
4 -0.577739  0.394475 -1.524400  16.505185  NaN
5  0.456884 -1.238733  0.453586  -4.868735  NaN
其中S是我需要计算的列,从一个设定值开始。 S的下一个值我需要是S的上一个值加上一些计算,如下所示:

df_test.S[1]=df_test.S[0]+df_test.D[1]*abs(df_test.C[1])*0.5
那么这个值应该由一个条件表达式计算。如果大于等于,例如10,则为其指定10(而不是计算),如果小于或等于5,则为其指定5

我在数据集上使用for循环,对每个元素运行我需要的等式。基本上它是这样工作的:

for i in range (1,df_test.shape[0]):
    df_test.S[i]=df_test.S[i-1]+df_test.D[i]*abs(df_test.C[i])*0.5
    if df_test.S[i]<5:
        df_test.S[i]=5
    elif df_test.S[i]>10:
        df_test.S[i]=10

范围内的i(1,df_测试形状[0]):
df_test.S[i]=df_test.S[i-1]+df_test.D[i]*abs(df_test.C[i])*0.5
如果df_试验S[i]10:
df_试验S[i]=10
8737行的代码大约需要20分钟才能完成


如果你需要任何澄清,请问我。提前感谢。

您可以直接在pandas中添加其他列的减影列。e、 g

df['S'] = df.A + df.B - df.C + df.apply(abs)**2
如果要将某些值wrt更改为条件,请使用.loc 用法:


您可以通过两个步骤轻松做到这一点:

df.loc[1:,'S']=df.loc[1:,“D”]*0.5*df.loc[1:,“C”].abs()计算所需的数值表达式
df[“S”]=df[“S”].cumsum()#将上一个添加到S的当前项中
#然后计算“如果”条件
df.loc[df[“S”]<5,'S']=5
df.loc[df[“S”]>10,'S']=10
==>对于循环,无

此(未测试)&不确定值在5到10之间时想要什么

df_测试['S'].iloc[0]=5
测向测试['S']=测向测试['S'].shift()+测向测试['D']*abs(测向测试['C'])*0.5
df_测试['S']=np.其中(df_测试['S']<5,5,df_测试['S']))
df_测试['S']=np.其中(df_测试['S']>10,10,df_测试['S'])

如果您的转换没有If条件,则可以对其进行处理

首先我们计算外生部分

exo=0.5*df['D'].multiply(df['C'].abs())

然后我们使用
lfilter

start = df['S'].iloc[0]
s = lfilter(np.array([1]), np.array([1, -1]), exo.shift(-1), zi=np.array([start]))[0]
df['S'].iloc[1:] = s[:-1]
在我的计算机上,这比循环解决方案快70倍左右


但遗憾的是,当你说上一个值时,它不会帮助你,因为缺少if条件

,你的意思是,计算的上一个值还是初始的上一个值?上一个计算值。初始值是从第一次计算开始的,实际上,它不是零而是一个固定值。您能提供代码来重现您的数据帧吗?还有预期的输出dataframeWell,我只是为了下面的例子制作了一个随机数据框:``df_test=pd.DataFrame(np.random.randn(6,4),columns=list('ABCD'))df_test.D=df_test.D*10 df_test['S']=np.nan df_test['S'][0]=5``这不是OP想要的,这样我影响了我不想要的计算结果。例如,如果计算值小于5,并且我为其指定了5,那么我需要将此5值作为下一个值计算的上一个值。如果我做了所有的计算,然后检查条件,我会改变结果,但这会改变S的第一个值too@MohitMotwani哪一部分
cumsum()
不会更改
df[“S”]
的第一个值,而不是cumsum(),df.D*df.C会更改第一行的值。我已经进行了更改。请检查。我认为这不起作用,因为您正在计算S列,求和,然后检查条件。我的目的是在计算完成后立即检查条件(数值计算并与以前的值求和),以便下一次“计算”可以取以前的计算值,或者,如果不满足条件,则取指定值。这有意义吗@在这里,第一步是计算S列,然后检查条件。我想在一个步骤中这样做,因此在每次“写入”之后,添加到当前值的前一个值应该是数值计算值,或者,如果它不满足条件,则是指定值。换句话说,如果上一个值为4.8,则将其设置为5,并使用5作为下一次计算的上一个值,而不是4.8。这有意义吗@TVgriek不幸的是,它确实具有if条件,但感谢您的努力:)
df['S'] = df.S.cumsum()
start = df['S'].iloc[0]
s = lfilter(np.array([1]), np.array([1, -1]), exo.shift(-1), zi=np.array([start]))[0]
df['S'].iloc[1:] = s[:-1]