在熊猫数据框中替换值无法与.replace()

时间:2020-03-12 01:34:05

标签: python python-3.x pandas dataframe

我有一个包含各种网格站及其与其他网格站的连接的数据集,我需要从该数据中绘制出传输线。看起来像这样(原始数据帧中大约有100行左右):

>df

    Name    Latitude    Longitude   Link 1  Link 2  Link 3  Link 4  Link 5  
0   A       34.466667   72.200000   B       NaN     NaN     NaN     NaN 
1   B       33.766667   72.366667   A       C       D       NaN     NaN
2   C       33.761500   72.434000   B       E       G       NaN     NaN

为了使事情变得容易,我创建了一个新的数据框,其索引如下:

>datax

        Latitude    Longitude   Link 1  Link 2  Link 3  Link 4  Link 5
Name                                                    
A       34.466667   72.200000   B       NaN     NaN     NaN     NaN 
B       33.766667   72.366667   A       C       D       NaN     NaN
C       33.761500   72.434000   B       E       G       NaN     NaN

我正在使用每个网格站的“链接”来绘制线路,这些链接向我显示了它所连接的其他网格站。由于每个网格站都显示了与其他网格站的连接,因此为了正确地映射线,我需要消除重复项,例如,如果我通过遍历数据帧的第一列来映射A和B之间的第一条线,则需要消除第二行中的该链接(即,删除第二行中“链接1”列中的“ A”),因此当我遍历第二行时,该行不会重复。为此,我尝试使用replace

datax.loc[datax.iloc[0]['Link 1']].replace(datax.index[0],np.nan)

此代码段确实替换了链接,并放入了nan,但未在原始数据帧中将其放置在适当的位置,因此我尝试了内置参数inplace,

datax.loc[datax.iloc[0]['Link 1']].replace(datax.index[0],np.nan, inplace=True)

但这似乎也没有。我有些是新手程序员,所以很抱歉,但是没有人知道我在做什么错,如何纠正这个错误,以及是否有更简单的方法可以解决我的问题。< / p>

编辑:

当我运行上面的代码片段时,我希望数据帧第二栏中的“链接1”成为NaN。

>datax

        Latitude    Longitude   Link 1  Link 2  Link 3  Link 4  Link 5
Name                                                    
A       34.466667   72.200000   B       NaN     NaN     NaN     NaN 
B       33.766667   72.366667   Nan     C       D       NaN     NaN
C       33.761500   72.434000   NaN     E       G       NaN     NaN

问题是代码可以执行此操作,但不会将其保存到适当的数据框中。由于我必须为原始数据帧执行数百次此过程,因此,我需要将值保存到数据帧中,而不是每次都创建新值,那样效率低下。

1 个答案:

答案 0 :(得分:2)

这是一种解决方案。

步骤1-第一步是沿列轴对“名称”和“链接1”的值进行排序。

datax[['Name', 'Link 1']].apply(sorted, axis=1)

这会给您这样的列表

0    [A, B]
1    [A, B]
2    [B, C]

步骤2-然后,您需要使用df.duplicated()

将它们转换为字符串(因为使用.apply(lambda x: ','.join(map(str, x)))时不接受列表)

步骤3-接下来,使用df.duplicated()查找重复项并将其存储在新列“ temp”中。

datax['temp'] = datax[['Name', 'Link 1']].apply(sorted, axis=1).apply(lambda x: ','.join(map(str, x))).duplicated(keep='first')

在这个阶段,您的df datax将是

  Name   Latitude  Longitude Link 1 Link 2 Link 3  Link 4  Link 5   temp
0    A  34.466667  72.200000      B    NaN    NaN     NaN     NaN  False
1    B  33.766667  72.366667    NaN      C      D     NaN     NaN   True
2    C  33.761500  72.434000      B      E      G     NaN     NaN  False

步骤4-现在,您可以使用np.where()并检查datax['temp']是否为True并相应地分配datax['Link 1']

datax['Link 1'] = np.where(datax['temp']==True, np.NaN, datax['Link 1'])

步骤5-之后,您可以使用temp

删除列datax.drop('temp', axis=1)

输出:

  Name   Latitude  Longitude Link 1 Link 2 Link 3  Link 4  Link 5
0    A  34.466667  72.200000      B    NaN    NaN     NaN     NaN
1    B  33.766667  72.366667    NaN      C      D     NaN     NaN
2    C  33.761500  72.434000      B      E      G     NaN     NaN

结合所有这些步骤-

datax['temp'] = datax[['Name', 'Link 1']].apply(sorted, axis=1).apply(lambda x: ','.join(map(str, x))).duplicated(keep='first')
datax['Link 1'] = np.where(datax['temp']==True, np.NaN, datax['Link 1'])
datax.drop('temp', axis=1)

最终解决方案- 我们可以扩展此解决方案,以比较“链接1”,“链接2”,“链接3”等与“名称”,然后分别设置“链接1”,“链接2”,“链接3”列。

for column in datax[['Link 1','Link 2','Link 3','Link 4','Link 5']]:
    datax['temp'] = datax[['Name', column]]\
        .fillna('').apply(sorted, axis=1)\
        .apply(lambda x: ','.join(map(str, x)))\
        .duplicated(keep='first')
    datax[column] = np.where(datax['temp']==True, np.NaN, datax[column])
    datax.drop('temp', axis=1, inplace=True)

print(datax)

输出:

  Name   Latitude  Longitude Link 1 Link 2 Link 3  Link 4  Link 5
0    A  34.466667  72.200000      B    NaN    NaN     NaN     NaN
1    B  33.766667  72.366667    NaN      C      D     NaN     NaN
2    C  33.761500  72.434000      B      E      G     NaN     NaN

让我知道这是否有帮助!