按索引值对pandas数据集进行重复数据删除,而不使用`networkx`

pxq42qpu  于 2023-08-01  发布在  其他
关注(0)|答案(6)|浏览(160)

请注意,我已经查看了此链接

Pandas and python: deduplication of dataset by several fields *

  • 7月18日更新:我的观点是,所有这些解决方案都指向避免索引,直到所有重复数据消除都执行完毕。感谢所有到目前为止回复的人**

我希望每个id的值只有一个唯一的code字段值。

  1. df = pd.DataFrame({'code':['A','A','B','C','D','A']},index=[1,1,1,2,3,3])
  2. df.index.name='id'

字符串
df:
| 代码| code |
| --| ------------ |
| 一个| A |
| 一个| A |
| B| B |
| C类| C |
| D级| D |
| 一个| A |
我想要的输出是:
| 代码| code |
| --| ------------ |
| 一个| A |
| B| B |
| C类| C |
| D级| D |
| 一个| A |
我设法做到这一点如下,* 但我不喜欢它 *。

  1. i=df.index.name
  2. df.reset_index().drop_duplicates().set_index(i)


原因如下:

  • 如果索引没有名称,则此操作将失败
  • 我不需要重新设置和设置索引
  • 这是一个相当常见的操作,这里有太多的墨水。

我想说的是:
df.groupby('id').drop_duplicates()
目前不支持。
有没有一个更Python的方法来做到这一点?

rpppsulh

rpppsulh1#

要使用.groupby有效地删除重复项,只需指定只保留第一行即可:

  1. from pandas import DataFrame
  2. df = DataFrame({"code": ["A", "A", "B", "C", "D", "A"]}, index=[1, 1, 1, 2, 3, 3])
  3. deduped = df.groupby(by=["code", df.index]).head(1)
  4. print(deduped)
  5. # code
  6. # 1 A
  7. # 1 B
  8. # 2 C
  9. # 3 D
  10. # 3 A

字符串
这个答案是基于this answer的,它还提出了几个额外的替代方案。

7xzttuei

7xzttuei2#

当你创建一个DataFrame时,将一个列表分配给一个索引,索引的名称将始终是None,一个对象。唯一一次索引的名称将不同的情况是,如果你将一个pd.Series对象分配给一个索引,其名称与“index"不同。

  1. df = pd.DataFrame({'code':['A','A','B','C','D','A']},index=[1,1,1,2,3,3])
  2. print(df.index.name) # -> 'None'
  3. # You need to specify name otherwise it will default to None, <class NoneType>
  4. index = pd.Series(data=[1,1,1,2,3,3], name='INDEX_NAME')
  5. df = pd.DataFrame({'code':['A','A','B','C','D','A']},index=index)
  6. print(df.index.name) # -> 'INDEX_NAME'

字符串
现在回到您的问题,当您从csv创建DataFrame时,您需要指定一个index_col,如果index_col有一个名称,那么它就是索引名称。在csv中可能没有名称,只有一个空字符串,那么它将没有名称,它将是None。如果不指定'index_col',将再次没有名称,它将是None,并且None不是字符串,它是<class 'NoneType'> '
范例:

  1. csv_string = ',A,B,C\n0,1,2,3\n1,4,5,6\n2,7,8,9'
  2. # Without specifying 'index_col' parameter
  3. df = pd.read_csv(io.StringIO(csv_string))
  4. print(df)
  5. '''
  6. Output:
  7. Unnamed: 0 A B C
  8. 0 0 1 2 3
  9. 1 1 4 5 6
  10. 2 2 7 8 9
  11. '''
  12. print(type(df.index.name)) # <class 'NoneType'>
  13. # By specifying index_col
  14. df = pd.read_csv(io.StringIO(csv_string), index_col=0)
  15. print(df)
  16. '''
  17. Output:
  18. A B C
  19. 0 1 2 3
  20. 1 4 5 6
  21. 2 7 8 9
  22. '''
  23. print(type(df.index.name)) # <class 'NoneType'>
  24. # This is because in the first column, on the first row, there is an empty string
  25. # Let's change that to a non-empty string
  26. csv_string = 'index,A,B,C\n0,1,2,3\n1,4,5,6\n2,7,8,9'
  27. df = pd.read_csv(io.StringIO(csv_string), index_col=0)
  28. print(df)
  29. '''
  30. Output:
  31. A B C
  32. index
  33. 0 1 2 3
  34. 1 4 5 6
  35. 2 7 8 9
  36. '''
  37. print(df.index.name, type(df.index.name)) # index <class 'str'>


当您像以前一样创建DataFrame时,或者像我展示的示例一样,您将始终知道索引的名称。

没有索引名的情况下怎么做:
*第一种方法(可能是最好的)

  1. index = pd.Series(data=[1,1,1,2,3,3])
  2. df = pd.DataFrame({'code':['A','A','B','C','D','A']},index=index)
  3. modified_df = df.reset_index().drop_duplicates(['index', 'code']).set_index('index')


与您的类似,因为如果没有名称,.reset_index()方法会将列命名为“index”。还有inplace参数,以防你想修改原始变量df而不是返回副本。

*第二种方法

  1. index = pd.Series(data=[1,1,1,2,3,3])
  2. df = pd.DataFrame({'code':['A','A','B','C','D','A']},index=index)
  3. modified_df = df.reset_index().drop_duplicates(['index', 'code'])
  4. modified_df.index = modified_df['index']
  5. modified_df = modified_df.drop(columns=['index'])


类似地,.drop()方法有一个inplace参数,以防你想修改原始的。如果inplace为true,则返回None,否则返回copy,所以在使用inplace参数时不应将返回值赋给任何东西。

**注意:**根据需要修改DataFrame后,df.index.name即使原来没有名称,也会有一个名称,为index。如果不需要索引名,可以自由地为索引名分配“无”值。

展开查看全部
xuo3flqw

xuo3flqw3#

要添加到您当前的方法中,请执行以下操作:
1.未命名的索引将转换为reset_index后面的列名“index”
1.第二步,可以将索引设置为第一列
下面是一个示例:

  1. df = pd.DataFrame({'code':['A','A','B','C','D','A']},index=[1,1,1,2,3,3])
  2. df.reset_index()
  3. df = df[~df.duplicated(keep="first")]
  4. df = df.set_index(df.iloc[:,0])
  5. #....or
  6. df = df.set_index(df.columns.to_list[0])

字符串

nhn9ugyo

nhn9ugyo4#

这是@luzede提供的第一个选项的简短版本:

  1. from pandas import DataFrame
  2. df = DataFrame({"id": [1, 1, 1, 2, 3, 3], "code": ["A", "A", "B", "C", "D", "A"]})
  3. deduped = df.drop_duplicates(subset=["id", "code"])
  4. print(deduped)
  5. # code id
  6. # 0 A 1
  7. # 2 B 1
  8. # 3 C 2
  9. # 4 D 3
  10. # 5 A 3

字符串
请注意,为了简单起见,dataframe是使用“id”作为单独的列来构造的(这产生了与问题中代码片段中基于索引的方法相同的结果)。

fwzugrvs

fwzugrvs5#

这里有一种方法可以实现结果:

  1. df = pd.DataFrame({'code':['A','A','B','C','D','A']},index=[1,1,1,2,3,3])
  2. df['id'] = df.reset_index()['index'].values
  3. print(df)
  4. # code id
  5. #1 A 1
  6. #1 A 1
  7. #1 B 1
  8. #2 C 2
  9. #3 D 3
  10. #3 A 3
  11. output = df.groupby(by=['code','id']).max().reset_index()
  12. print(output)
  13. # code id
  14. #0 A 1
  15. #1 A 3
  16. #2 B 1
  17. #3 C 2
  18. #4 D 3

字符串

展开查看全部
tpgth1q7

tpgth1q76#

  1. import pandas as pd
  2. df = pd.DataFrame({'code': ['A', 'A', 'B', 'C', 'D', 'A']}, index=[1, 1, 1, 2, 3, 3])
  3. df.index.name = 'id'
  4. df = df.drop_duplicates(keep='first')
  5. print(df)

字符串

相关问题