我需要修改python pandas数据帧。考虑
Id Col
1 a
2 a
3 p
3 sp
4 n
4 sn
5 b
6 c
是我的数据框。 Ids 3和4出现两次。对于具有Id 3的行,Col具有值p和sp。类似地,对于Id 4,我们在Col中看到值n和sn。我想删除具有Col作为Id的p的行和具有作为n的Id的行。因此,我将我的数据帧看起来像
Id Col
1 a
2 a
3 sp
4 sn
5 b
6 c
基本上,这就是我需要做的事情
检查是否有任何重复。让我们假设重复项只是成对出现而不是三元组或更多。
然后,如果Col的值相同,那么我们只保留一行。
我怎样才能实现这一目标?
修改
实际上,理想情况下我需要在决定要删除哪一行之前进行检查。假设我知道有多行具有Id 3,并且相应的Col值为
p
sp
现在我想在列表中收集这些值
['p','sp']
并将其发送到类似
的功能def giveMeBest(paramList):
bestVal = ""
for param in paramList:
'''
some logic goes here
'''
return bestVal
然后我只保留Col中值为bestVal的行。请注意,这也允许我处理任意数量的重复。
EDIT2
感谢rurp的回答。我只是最后一个请求。我试图通过执行以下操作来清理我的数据框
for x in result:
resVal = getVal(x[1])
'''
getVal returns the appropriate value that i want to be set in
my dataframe. Note that x[1] will denote the array of duplicate values in Col
'''
resData = resData[(resData.Id == x[0]) & (resData.Col!=resVal)]
但这仍然不会删除行
print(resData[resData.Id==3])
Id Col
3 p
3 sp
我甚至试过
resData = resData.drop(resData[(resData.Id == int(x[0])) & (resData.Col!=resSent)].index)
但它仍显示重复的行。
如何从数据框中删除多行?
解决了丢弃行
这是我怎么做的
idx = []
for x in result:
resVal = getVal(x[1])
idx.append(resData[(resData.Id == x[0]) & (resData.Col!= resVal)].index.tolist())
然后,只是
for j in idx:
resData = resData.drop(j)
答案 0 :(得分:2)
假设s
总是最后一次,你可以使用drop_duplicates:
In [11]: df.drop_duplicates(take_last=True, subset=["Col"])
Out[11]:
Id Col
1 2 a
2 3 p
3 3 sp
4 4 n
5 4 sn
6 5 b
7 6 c
如果没有这样排序他们就是这样。最简单的方法是提取is_s
列(例如.str.startswith("s")
),并在删除重复项之前对其进行排序。
答案 1 :(得分:1)
您可以创建一个元组列表,其中包含多次出现的“Id”值以及“Col”中相应值的列表。然后可以将这些值传递给您的函数以确定要删除的值。
import pandas as pd
ids = [1,2,3,3,4,4,5,6]
cols = ['a', 'a', 'p', 'sp', 'n', 'sn', 'b', 'c']
df = pd.DataFrame({'Id':ids, 'Col':cols})
counts = df['Id'].value_counts()
values = [x for x in counts.index if counts[x]>1]
result = []
for e in values:
vals = df[df['Id'] == e].Col.value_counts().index.values
result.append((e, vals))
这会给你
for n in result:
print n
(4, array(['n', 'sn'], dtype=object))
(3, array(['sp', 'p'], dtype=object))
希望这有帮助。