【问题标题】:Replacing values inplace in a pandas dataframe work not working with .replace()在熊猫数据框中就地替换值不适用于 .replace()
【发布时间】:2020-03-12 01:34:05
【问题描述】:

我有一个包含各种网格站及其与其他网格站连接的数据集,我需要从这些数据中绘制出传输线。它看起来像这样(原始数据框中大约有 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 之间的第一条线,我需要消除此链接(即删除第二行 Link 1 列中的“A”)在第二行中,因此当我遍历第二行时该行不会重复。为此,我尝试使用替换,

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

这个 sn-p 确实替换了链接并放入了 nan 但没有在原始数据帧中执行它,所以我尝试了内置参数 inplace,

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

但这似乎也不行。我有点像新手编码员,所以很抱歉,但有谁知道我做错了什么,以及如何纠正这个错误,以及是否有另一种更简单的方法来解决这个问题。

编辑:

当我运行上面的代码 sn-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

问题是代码确实这样做了,但没有将其保存到数据帧中。由于我必须为原始数据帧执行数百次此过程,因此我需要将值保存到数据帧中,而不是每次都创建新值,这将是低效的地狱。

【问题讨论】:

  • 如何使数据框可粘贴?你能在这里指导我吗?我认为 pd.read_clipboard() 可以很容易地完成这项工作
  • 对不起,这是我的错误页面评论。你能提供一个你想要的输出示例吗?
  • 我已经编辑了原始问题并添加了我需要的输出示例。希望它可以帮助您帮助我解决这个问题。
  • @HamzaWaheed 你在看这个吗? datax.at['A', 'Link 1'] = np.NaN
  • @davidbilla,对于 .at,我需要有准确的数据索引,而 replace 可以在列中找到值本身,这更加理想,因为数据可以位于任何“链接”处仅链接 1

标签: python python-3.x pandas dataframe


【解决方案1】:

这是一种解决方案。

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

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

这会给你一个这样的列表

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

第 2 步 - 然后您需要使用 .apply(lambda x: ','.join(map(str, x))) 将这些转换为字符串(因为使用 df.duplicated() 时不接受列表)

第 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 步 - 您可以在此之后使用 datax.drop('temp', axis=1) 删除列 temp

输出:

  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

如果这有帮助,请告诉我!

【讨论】:

  • 谢谢老兄,您的解决方案非常完美,我刚刚制作了一个带有重复传输线的新数据帧,然后使用您的代码清除了重复项,就像一个魅力。非常感谢。
  • 很高兴我能提供帮助
猜你喜欢
  • 1970-01-01
  • 2017-09-10
  • 1970-01-01
  • 2019-02-02
  • 1970-01-01
  • 2018-09-29
  • 1970-01-01
  • 2022-01-11
相关资源
最近更新 更多