Python 如何分析此数据帧中的所有重复条目?
我希望能够计算熊猫数据框架中数据的描述性统计,但我只关心重复的条目。例如,假设我创建的数据框是:Python 如何分析此数据帧中的所有重复条目?,python,pandas,dataframe,Python,Pandas,Dataframe,我希望能够计算熊猫数据框架中数据的描述性统计,但我只关心重复的条目。例如,假设我创建的数据框是: import pandas as pd data={'key1':[1,2,3,1,2,3,2,2],'key2':[2,2,1,2,2,4,2,2],'data':[5,6,2,6,1,6,2,8]} frame=pd.DataFrame(data,columns=['key1','key2','data']) print frame key1 key2 data 0 1
import pandas as pd
data={'key1':[1,2,3,1,2,3,2,2],'key2':[2,2,1,2,2,4,2,2],'data':[5,6,2,6,1,6,2,8]}
frame=pd.DataFrame(data,columns=['key1','key2','data'])
print frame
key1 key2 data
0 1 2 5
1 2 2 6
2 3 1 2
3 1 2 6
4 2 2 1
5 3 4 6
6 2 2 2
7 2 2 8
如您所见,行0、1、3、4、6和7都是重复的(使用“key1”和“key2”)。但是,如果我像这样索引此数据帧:
frame[frame.duplicated(['key1','key2'])]
我明白了
key1 key2 data
3 1 2 6
4 2 2 1
6 2 2 2
7 2 2 8
(即,第一行和第二行不会显示,因为复制方法没有将它们索引为True)
这是我的第一个问题。我的第二个问题涉及如何从这些信息中提取描述性统计信息。暂时忘记丢失的重复项,假设我要计算重复项的.min()和.max()(以便获得范围)。我可以在groupby对象上使用groupby和以下方法,如下所示:
a.groupby(['key1','key2']).min()
给
key1 key2 data
key1 key2
1 2 1 2 6
2 2 2 2 1
我想要的数据显然就在这里,但我提取它的最佳方式是什么?我如何索引结果对象以获得我想要的数据(即key1、key2、data info)?这里有一个可能的解决方案,可以返回两列(即第0、1、3、4、6、7行)中的所有重复值: (Edit:实际上,
df.duplicated(take_last=True)| df.duplicated()
方法更整洁。)
要查询groupby
操作的结果,可以使用loc
。例如:
>>> dups = frame[frame.key1.isin(key1_dups) & frame.key2.isin(key2_dups)]
>>> grouped = dups.groupby(['key1','key2']).min()
>>> grouped
data
key1 key2
1 2 5
2 2 1
>>> grouped.loc[1, 2]
data 5
Name: (1, 2), dtype: int64
或者,通过重置两个索引,将分组后的返回到“正常外观”数据帧:
>>> grouped.reset_index(level=0).reset_index(level=0)
key2 key1 data
0 2 1 5
1 2 2 1
为熊猫0.17或更高版本编辑:
由于duplicated()
方法的take_last
参数自0.17以来支持新的keep
参数,请参阅以了解正确的方法:
- 使用
keep=False
调用duplicated()
方法,即frame.duplicated(['key1','key2',keep=False)
因此,为了提取该特定问题所需的数据,以下内容就足够了:
In [81]: frame[frame.duplicated(['key1', 'key2'], keep=False)].groupby(('key1', 'key2')).min()
Out[81]:
data
key1 key2
1 2 5
2 2 1
[2 rows x 1 columns]
有趣的是,熊猫0.17的这种变化可能部分归因于这个问题,如中所述
对于0.17之前的版本:
我们可以使用方法的take_last
参数:
take_last
:boolean
,默认值False
对于一组不同的重复行,将除最后一行外的所有行标记为重复。默认情况下,除第一行外的所有行都要标记
如果我们将take_last
的值设置为True
,我们将标记除最后一个重复行以外的所有行。将此值与其默认值False
相结合,该默认值标记除第一个重复行以外的所有行,允许我们标记所有重复行:
In [76]: frame.duplicated(['key1', 'key2'])
Out[76]:
0 False
1 False
2 False
3 True
4 True
5 False
6 True
7 True
dtype: bool
In [77]: frame.duplicated(['key1', 'key2'], take_last=True)
Out[77]:
0 True
1 True
2 False
3 False
4 True
5 False
6 True
7 False
dtype: bool
In [78]: frame.duplicated(['key1', 'key2'], take_last=True) | frame.duplicated(['key1', 'key2'])
Out[78]:
0 True
1 True
2 False
3 True
4 True
5 False
6 True
7 True
dtype: bool
In [79]: frame[frame.duplicated(['key1', 'key2'], take_last=True) | frame.duplicated(['key1', 'key2'])]
Out[79]:
key1 key2 data
0 1 2 5
1 2 2 6
3 1 2 6
4 2 2 1
6 2 2 2
7 2 2 8
[6 rows x 3 columns]
现在我们只需要使用andmin
方法,我相信输出的格式是必需的:
In [81]: frame[frame.duplicated(['key1', 'key2'], take_last=True) | frame.duplicated(['key1', 'key2'])].groupby(('key1', 'key2')).min()
Out[81]:
data
key1 key2
1 2 5
2 2 1
[2 rows x 1 columns]
要获得Pandas版本为0.17的所有重复条目的列表,只需在函数中设置“keep=False”
frame[frame.duplicated(['key1','key2'],keep=False)]
key1 key2 data
0 1 2 5
1 2 2 6
3 1 2 6
4 2 2 1
6 2 2 2
7 2 2 8
感谢ajcr的响应。如果我想循环最后一个对象中的条目,拉出每个条目的key1、key2和数据值,那么正常的方法是什么?我只是捡起熊猫……事实上,我在这里找到了一个不错的解决方案:@gammapoint-完全没有问题。Yes将循环数据帧的行(虽然如果可能的话,通常最好避免以这种方式循环…这可能是低效的)。注意:对于那些想知道为什么我在最后一个命令中有额外的“key1”和“key2”列的人来说,这是因为我使用的是Pandas 0.07(这在Ubuntu repos中是可用的)。如果我升级到Pandas 0.14,我就不会再得到它了(如下面ajcr和Yoel的回答所示)。
frame[frame.duplicated(['key1','key2'],keep=False)]
key1 key2 data
0 1 2 5
1 2 2 6
3 1 2 6
4 2 2 1
6 2 2 2
7 2 2 8