2016-11-16 80 views
1

基于另一列的值,我想用for循环填充新列。遗憾的是没有得到我需要的结果;尝试用for循环填充数据框中的新列

profit = [] 

# For each row in the column, 
for row in df3['Result']: 
    # if value is; 
    if row == 'H': 
     # Append a Profit/Loss 
     profit.append(df3['column value H']) 
    # else, if value is, 
    elif row == 'D': 
     # Append a Profit/Loss 
     profit.append(df3['column value D'])   
    # otherwise, 
    else: 
     # Append a Profit/Loss 
     profit.append(df3['column value A']) 

df3['profit'] = profit 
+0

请显示'''df3.head()''' - 如果没有太多的列。 - 和你想要的结果。 – wwii

回答

1

我想你需要双numpy.where

df3['profit'] = np.where(df3['Result'] == 'H', df3['column value H'], 
       np.where(df3['Result'] == 'D', df3['column value D'], df3['column value A'])) 

样品:

df3 = pd.DataFrame({'Result':['H','D','E'], 
        'column value H':[4,5,6], 
        'column value D':[7,8,9], 
        'column value A':[1,3,5]}) 

print (df3) 
    Result column value A column value D column value H 
0  H    1    7    4 
1  D    3    8    5 
2  E    5    9    6 

df3['profit'] = np.where(df3['Result'] == 'H', df3['column value H'], 
       np.where(df3['Result'] == 'D', df3['column value D'], df3['column value A'])) 

print (df3) 
    Result column value A column value D column value H profit 
0  H    1    7    4  4 
1  D    3    8    5  8 
2  E    5    9    6  5 

时序

In [198]: %timeit (jez(df3)) 
100 loops, best of 3: 7.59 ms per loop 

In [199]: %timeit (wwii(df4)) 
1 loop, best of 3: 1.49 s per loop 

In [200]: %timeit (wwii1(df5)) 
1 loop, best of 3: 4.48 s per loop 

代码进行测试

df3 = pd.DataFrame({'Result':['H','D','E'], 
        'column value H':[4,5,6], 
        'column value D':[7,8,9], 
        'column value A':[1,3,5]}) 

print (df3) 
df3 = pd.concat([df3]*10000).reset_index(drop=True) 

df4 = df3.copy() 
df5 = df3.copy() 

def jez(df3): 
    df3['profit'] = np.where(df3['Result'] == 'H', df3['column value H'], 
        np.where(df3['Result'] == 'D', df3['column value D'], df3['column value A'])) 

    return (df3) 

def foo(series): 
    # d maps Result column values to DataFrame/Series column names 
    d = {'H':'column value H', 'D':'column value D'} 
    try: 
     return series[d[series['Result']]] 
    except KeyError as e: 
     return series['column value A'] 

def wwii(df3): 
    df3['Profit'] = df3.apply(foo, axis = 1) 
    return df3 

def wwii1(df3): 
    profit = [] 
    for row in df3.iterrows(): 
     series = row[1] 
     if series.Result == 'H': 
      # Append a Profit/Loss 
      profit.append(series['column value H']) 
     # else, if value is, 
     elif series.Result == 'D': 
      # Append a Profit/Loss 
      profit.append(series['column value D']) 
     # otherwise, 
     else: 
      # Append a Profit/Loss 
      profit.append(series['column value A']) 

    df3['profit'] = profit   
    return df3    

print (jez(df3))  
print (wwii(df4))  
print (wwii1(df5))  
+0

谢谢,这和其他两种解决方案一样有效。如果要进行额外的计算,我更喜欢哪一个? – Zanshin

+0

顺便说一句,我已经计时了,它们之间没有太大的区别。 – Zanshin

+0

如果使用较大的数据帧,例如'30k'行,'numpy.where'解决方案是最快的。小DataFrame也许差异很小。 – jezrael

0

你没有使用你的操作的任何行的信息。您可能注意到,df3['column value H']会为您想要操作的行返回一个序列而不是单个值。

要修复您的for循环使用DataFrame.iterrows()它返回(索引,系列)元组为每行。然后,您可以通过series['column name']访问该行中的每一列。

for row in df3.iterrows(): 
    series = row[1] 
    if series.Result == 'H': 
     # Append a Profit/Loss 
     profit.append(series['column value H']) 
    # else, if value is, 
    elif series.Result == 'D': 
     # Append a Profit/Loss 
     profit.append(series['column value D'])   
    # otherwise, 
    else: 
     # Append a Profit/Loss 
     profit.append(series['column value A']) 

另一种方法是编写一个函数,采取了一系列作为参数,处理它,并返回所需的值。然后使用DataFrame.apply() - 指定axis = 1在行上应用该函数。

def foo(series): 
    # d maps Result column values to DataFrame/Series column names 
    d = {'H':'column value H', 'D':'column value D'} 
    try: 
     return series[d[series['Result']]] 
    except KeyError as e: 
     return series['column value A'] 

df3['Profit'] = df3.apply(foo, axis = 1) 

double where proposed by @jezrael可能是最好的,如果数据帧没有任何复杂得多,假定(无定的例子),但如果有更多的可能列以上的条件下,它可能会导致混乱。