如何迭代熊猫数据框并创建新列

Posted

技术标签:

【中文标题】如何迭代熊猫数据框并创建新列【英文标题】: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 【参考方案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

【讨论】:

以上是关于如何迭代熊猫数据框并创建新列的主要内容,如果未能解决你的问题,请参考以下文章

如何拆分pyspark数据框并创建新列

如何将列表中的值分配给熊猫数据框并控制每个列表元素在数据框中的分布/频率

迭代数据框并根据一列的值在具有前一行值的新列中执行操作

如何在遍历熊猫数据框时创建新列并插入行值

如何比较两个熊猫数据框并返回将它们相互映射的索引?

如何根据熊猫中的行值创建新列