我正在处理一个非常大的数据框,我使用pandas
进行分析。
数据框的结构如下
import pandas as pd
df = pd.read_csv("data.csv")
df.head()
Source Target Weight
0 0 25846 1
1 0 1916 1
2 25846 0 1
3 0 4748 1
4 0 16856 1
问题是我想要删除所有"重复"。从某种意义上说,如果我已经有一个包含Source
和Target
的行,我不希望在另一行上重复此信息。
例如,行号0和2是"重复"从这个意义上讲,只保留其中一个。
摆脱所有"重复的简单方法"是
for index, row in df.iterrows():
df = df[~((df.Source==row.Target)&(df.Target==row.Source))]
然而,由于我的数据框有大约300万行,因此这种方法非常慢。你认为有更好的方法吗?
答案 0 :(得分:3)
创建两个临时列以保存minimum(df.Source, df.Target)
和maximum(df.Source, df.Target)
,然后按duplicated()
方法检查重复的行:
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randint(0, 5, (20, 2)), columns=["Source", "Target"])
df["T1"] = np.minimum(df.Source, df.Target)
df["T2"] = np.maximum(df.Source, df.Target)
df[~df[["T1", "T2"]].duplicated()]
答案 1 :(得分:0)
不需要(像往常一样)使用带有数据帧的循环。使用Series.isin
方法:
首先从这开始:
df = pandas.DataFrame({
'src': [0, 0, 25, 0, 0],
'tgt': [25, 12, 0, 85, 363]
})
print(df)
src tgt
0 0 25
1 0 12
2 25 0
3 0 85
4 0 363
然后选择src
中不存在tgt
的所有位置:
df[~(df['src'].isin(df['tgt']) & df['tgt'].isin(df['src']))]
src tgt
1 0 12
3 0 85
4 0 363
答案 2 :(得分:0)
您的来源和目标似乎是互斥的(即您可以拥有一个,但不能同时拥有两个)。为什么不将它们加在一起(例如25846 + 0)以获得唯一标识符。然后,您可以删除不需要的Target
列(减少内存),然后删除重复项。如果您的权重不相同,默认情况下它将采用第一个权重。
df.Source += df.Target
df.drop('Target', axis=1, inplace=True)
df.drop_duplicates(inplace=True)
>>> df
Source Weight
0 25846 1
1 1916 1
3 4748 1
4 16856 1