无法替换数据框中的列值

时间:2015-10-25 19:09:41

标签: python pandas indexing dataframe

我的数据框如下:

super.init(data: data, scale: scale)

我尝试解码列 date_time ID Direction 0 2015-05-22 05:37:59 10.0 1 2015-05-22 05:37:59 10.0 TRUE 2 2015-05-22 05:37:59 10.0 3 2015-05-26 05:56:59 9.0 4 2015-05-26 05:56:59 9.0 TRUE 5 2015-05-26 05:56:59 10.0 TRUE ...................... ...... ...... 的值,如果相应的Direction为9.0,则将TRUE替换为right,如果相应ID则为left。 s 10.0

我正在尝试以下代码:

def directions():
    for index, row in df.iterrows():
        if row['ID']=='9.0':
            row['Direction'] = row['Direction'].map({'TRUE': 'right', '': ''})
        elif row['ID']=='10.0':
            row['Direction'] = row['Direction'].map({'TRUE': 'left', '': ''})
    return df

它不会抛出错误,但它不会改变现有数据框中的任何内容,您知道哪里可能出现问题吗? 我考虑过使用iloc loc,但我对这种方法并不是很强,所以如果你知道如何更好地将它们应用到这个案例中,那么它可以解决我的问题

1 个答案:

答案 0 :(得分:1)

我认为问题是迭代器返回行的副本,修改副本不会修改原始数据。您可以使用loc属性修改数据视图,如下所示:

def directions(df):
    df.loc[(df['ID'] == 9) & (df['Direction'] == 'TRUE'), 'Direction'] = 'right'
    df.loc[(df['ID'] == 10) & (df['Direction'] == 'TRUE'), 'Direction'] = 'left'
    return df

编辑 - loc的一些解释:

您可以将loc视为以灵活的方式索引数据框的行和列的方法。语法为df.loc[row_indicator, col_indicator]。 row / col指示器非常灵活:它可以是布尔掩码,索引,切片,索引列表等。它与NumPy中可用的各种索引方案非常相似。

让我们详细了解这个解决方案的作用。我们首先构造一个布尔掩码,指示ID为9的位置:

>>> mask_ID9 = (df['ID'] == 9)
>>> mask_ID9
0    False
1    False
2    False
3     True
4     True
5    False
Name: ID, dtype: bool

我们可以使用这个掩码来索引数据帧,并访问掩码为True的所有行:

>>> df.loc[mask_ID9]
             date_time  ID Direction
3  2015-05-26-05:56:59   9        ''
4  2015-05-26-05:56:59   9     right

但是我们还希望将其限制为Direction为TRUE的列:

>>> mask_TRUE = (df['Direction'] == 'TRUE')
>>> mask_TRUE
0    False
1     True
2    False
3    False
4     True
5     True
Name: Direction, dtype: bool

现在我们可以将它们与逻辑AND运算符结合起来,找到两个条件都为True的位置:

>>> mask_ID9 & mask_TRUE
0    False
1    False
2    False
3    False
4     True
5    False
dtype: bool

使用此索引将仅返回第4行,因为它是唯一满足这些条件的地方:

>>> df.loc[mask_ID9 & mask_TRUE]
             date_time  ID Direction
4  2015-05-26-05:56:59   9     right

但我们不想要整个行,我们只需要'Direction'列,因此我们将其添加到loc调用中:

>>> df.loc[mask_ID9 & mask_TRUE, 'Direction']
4    TRUE
Name: Direction, dtype: object

现在我们可以为DataFrame的这一部分分配适当的值:

>>> df.loc[mask_ID9 & mask_TRUE, 'Direction'] = 'right'
>>> df
             date_time  ID Direction
0  2015-05-22-05:37:59  10        ''
1  2015-05-22-05:37:59  10      TRUE
2  2015-05-22-05:37:59  10        ''
3  2015-05-26-05:56:59   9        ''
4  2015-05-26-05:56:59   9     right
5  2015-05-26-05:56:59  10      TRUE

更改left值的工作方式类似。