如果我有像这样的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)一样好。
我该怎么办呢?
答案 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)
将依次产生每组组合,而不是一次性生成它们。