pandas:如何检查一列中的重复值并从另一列创建成对的值列表

时间:2015-03-13 01:03:46

标签: python pandas dataframe

如果我有像这样的pandas数据框:

Out[2]: 
          A         B
0       200         5
2       100        11
4       200         3
6       300         6
8       300         9
10      200         4

我希望能够检查A列中的重复值(这里重复200和300),然后从B列中与重复行相同的行输出成对值列表。 A列中的值如下:

[(5,3),(5,4),(3,4),(6,9)]

元组中数字的顺序并不重要,即(5,3)与(3,5)一样好。

我该怎么办呢?

2 个答案:

答案 0 :(得分:1)

定时器设置用于比较一系列数据大小:

import itertools
import pandas as pd
import timeit

size = 100
setup = '''
import pandas as pd
from numpy.random import randint

size = %s

rv = pd.DataFrame(randint(0, high=9, size=(size,2)), columns=['A','B'])
rvg = rv.groupby('A')


def explicit(rvg):
    total = []
    for k, v in rvg.B:
        if len(v)> 1:
            total.append(list(itertools.combinations(v, 2)))
    return total


def listcomp(rvg):
    return [list(itertools.combinations(v[1:][0], 2)) for v in rvg.B if len(v[1:][0])>1]

'''
for size in (100, 500, 1000, 5000, 10000):
    print('%d records:'%size)
    print('Explicit loop: '),
    print(min(timeit.Timer('explicit(rvg)', setup=setup%size).repeat(7, 1000)))
    print('Implicit loop: '),
    print(min(timeit.Timer('listcomp(rvg)', setup=setup%size).repeat(7, 1000)))
'''
# to verify that they give the same results
print(explicit(rvg))
print('\n')
print(listcomp(rvg))
'''

隐含最终更快:

100 records:
Explicit loop:  1.04004383087
Implicit loop:  1.04814505577
500 records:
Explicit loop:  2.24344801903
Implicit loop:  2.28265190125
1000 records:
Explicit loop:  6.24254918098
Implicit loop:  6.72238111496
5000 records:
Explicit loop:  194.443366051
Implicit loop:  194.122081041
10000 records:
Explicit loop:  778.750103951
Implicit loop:  777.272083044

与dawg的发电机版本相比,留给其他人做练习。

答案 1 :(得分:0)

与cphlewis差不多,但使用Pandas:

>>> df
     A   B
0  200   5
1  100  11
2  200   3
3  300   6
4  300   9
5  200   4
>>> import itertools as it
>>> [list(it.combinations(t[1:][0], 2)) for t in df.groupby('A').B if len(t[1:][0])>1]
[[(5, 3), (5, 4), (3, 4)], [(6, 9)]]

由于it.combinations(t[1:][0], 2)df.groupby('A').B都是迭代器,你可能想写这样的东西以便更友好:

def combo(df):
    for t in df.groupby('A').B:
        if len(t[1:][0])>1:
             yield it.combinations(t[1:][0], 2)

将依次产生每组组合,而不是一次性生成它们。