【问题标题】:Modifying Python DataFrame rows with duplicates修改具有重复项的 Python DataFrame 行
【发布时间】:2015-10-02 16:27:40
【问题描述】:

我需要修改一个 python pandas 数据框。考虑

Id    Col
1     a
2     a
3     p
3     sp
4     n
4     sn
5     b
6     c

是我的数据框。 ID 3 和 4 出现两次。对于 ID 为 3 的行,Col 具有值 p 和 sp。同样,对于 Id 4,我们在 Col 中看到值 n 和 sn。我想删除对于 Id 3 具有 Col 作为 p 的行和对于 Id 4 具有 Col 作为 n 的行。所以我希望我的数据框看起来像

Id    Col
1     a
2     a
3     sp
4     sn
5     b
6     c

所以基本上,这就是我需要做的事情

  1. 检查是否有任何重复项。让我们假设重复只成对出现,而不是三倍或更多。

  2. 那么如果Col的值相同,那么我们只保留一个这样的行。

  3. 如果 Col 中的值为 p 和 sp,我想保留有 sp 的行。
  4. 如果 Col 中的值为 n 和 sn,我想保留有 sn 的行。

我怎样才能做到这一点?

编辑

实际上,理想情况下,我需要在决定删除哪一行之前进行检查。假设我知道 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)

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    假设ss 总是最后一个,您可以使用 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"))并在删除重复项之前按该列排序。

    【讨论】:

    • 谢谢!非常好的建议。请查看编辑,因为我认为我需要更具体的内容
    【解决方案2】:

    您可以创建一个元组列表,其中包含多次出现的每个“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))
    

    希望对您有所帮助。

    【讨论】:

    • 完美!正是我需要的:) 现在我可以运行我的逻辑并清理数据。非常感谢:)
    • 最后,现在删除行的有效方法是什么?我想双循环是最直接的
    猜你喜欢
    • 2022-01-14
    • 2020-11-16
    • 2018-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 1970-01-01
    相关资源
    最近更新 更多