【问题标题】:How to iterate over pandas dataframe and create new column如何迭代熊猫数据框并创建新列
【发布时间】:2017-02-13 21:36:22
【问题描述】:

我有一个有 2 列的 pandas 数据框。我想遍历它的行并基于第 2 列中的字符串我想在新创建的第 3 列中添加一个字符串。我试过了:

for i in df.index:
    if df.ix[i]['Column2']==variable1:
        df['Column3'] = variable2
    elif df.ix[i]['Column2']==variable3:
        df['Column3'] = variable4

print(df)

但生成的数据框在第 3 列中只有变量 2。

有什么想法我还能做到这一点吗?

【问题讨论】:

  • 您可以使用for i, r in df.iterrows() 获取i 作为索引和r 作为一系列行值。这使得编写 if、elif 条件更容易if r.Column2==variable1:
  • 我刚刚意识到您的主要问题是您将整个列 Column3 设置为 ALL i 的变量 2 和变量 4。您只得到 variable2,因为 variable1 是 Column2 中的最后一个元素。换句话说,只需使用df.ix[i, 'Column3'] = variable2df.ix[i, 'Column3'] = variable4

标签: python loops pandas conditional-statements multiple-columns


【解决方案1】:

我认为你可以使用双numpy.where,循环更快:

df['Column3'] = np.where(df['Column2']==variable1, variable2, 
                np.where(df['Column2']==variable3, variable4))

如果两个条件都为False,则需要添加变量:

df['Column3'] = np.where(df['Column2']==variable1, variable2, 
                np.where(df['Column2']==variable3, variable4, variable5))

示例:

df = pd.DataFrame({'Column2':[1,2,4,3]})
print (df)
   Column2
0        1
1        2
2        4
3        3

variable1 = 1
variable2 = 2
variable3 = 3
variable4 = 4
variable5 = 5

df['Column3'] = np.where(df['Column2']==variable1, variable2, 
                np.where(df['Column2']==variable3, variable4, variable5))

print (df)
   Column2  Column3
0        1        2
1        2        5
2        4        5
3        3        4

另一种解决方案,谢谢Jon Clements:

df['Column4'] = df.Column2.map({variable1: variable2, variable3:variable4}).fillna(variable5)
print (df)
   Column2  Column3  Column4
0        1        2      2.0
1        2        5      5.0
2        4        5      5.0
3        3        4      4.0

【讨论】:

  • 或者可能:df.Column2.map({1: 'foo', 3: 'bar'}).fillna('') - 那么你就有了你的条件(非嵌套在单操作字典中)和fillna 作为默认值
  • 是的,仅转换为float 并不好,但如果变量为floatstring 则效果很好。如果int,则只需要.astype(int)。谢谢你。
  • 感谢 Jezrael,它做得很好。如果我不是太厚脸皮,这可能非常困难,但是考虑到当前并非两个变量的行数相同,我现在如何公平地用变量 2 或 4 替换变量 5。在您的示例中,如果第 4 列是
  • 2.0 5.0 5.0 4.0 4.0 4.0。在这种情况下,2 5's 应该变成 2's
  • @Andei Cozma - 我离开了我的电脑。所以我想你可以问另一个问题。小建议检查this,不要忘记添加所需的输出。
【解决方案2】:

你也可以试试这个(如果你想保留你使用的for循环):

new_column = []

for i in df.index:
    if df.ix[i]['Column2']==variable1:
        new_column.append(variable2)
    elif df.ix[i]['Column2']==variable3:
        new_column.append(variable4)
    else : #if both conditions not verified
        new_column.append(other_variable)

df['Column3'] = new_column

【讨论】:

    【解决方案3】:

    首先,不需要循环遍历每个索引,只需使用 boolean indexing 内置的 pandas。这里的第一行,我们收集Column2 中与variable1 相同的所有值,并将Column3 中的同一行设置为variable2

    df.ix[df.Column2==variable1, 'Column3'] = variable2
    df.ix[df.Column2==variable3, 'Column3'] = variable4
    

    一个简单的例子是

    import pandas as pd
    
    df = pd.DataFrame({'Animal':['dog', 'fish', 'fish', 'dog']})
    print(df)
    
        Animal
    0   dog
    1   fish
    2   fish
    3   dog
    
    df.ix[df.Animal=='dog', 'Colour'] = 'brown'
    df.ix[df.Animal=='fish', 'Colour'] = 'silver'
    print(df)
    
        Animal  Colour
    0   dog     brown
    1   fish    silver
    2   fish    silver
    3   dog     brown
    

    使用&| 等多个条件可以非常轻松地构建上述方法以获取布尔索引。

    df = pd.DataFrame({'Animal':['dog', 'fish', 'fish', 'dog'], 'Age': [1, 3, 2, 10]})
    print(df)
    
       Age Animal
    0    1    dog
    1    3   fish
    2    2   fish
    3   10    dog
    
    df.ix[(df.Animal=='dog') & (df.Age > 8), 'Colour'] = 'grey' # old dogs go grey
    df.ix[(df.Animal=='dog') & (df.Age <= 8), 'Colour'] = 'brown'
    df.ix[df.Animal=='fish', 'Colour'] = 'silver'
    print(df)
    
       Age Animal  Colour
    0    1    dog   brown
    1    3   fish  silver
    2    2   fish  silver
    3   10    dog    grey
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-08
      • 1970-01-01
      • 2018-07-07
      • 2019-03-15
      • 2020-05-17
      • 2015-12-09
      • 1970-01-01
      • 2021-07-20
      相关资源
      最近更新 更多