我有一个包含各种网格站及其与其他网格站的连接的数据集,我需要从该数据中绘制出传输线。看起来像这样(原始数据帧中大约有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
问题是代码可以执行此操作,但不会将其保存到适当的数据框中。由于我必须为原始数据帧执行数百次此过程,因此,我需要将值保存到数据帧中,而不是每次都创建新值,那样效率低下。
答案 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
让我知道这是否有帮助!