熊猫:加快最小值提取

时间:2017-05-27 17:42:34

标签: python performance sorting pandas

我有一个巨大的数据框(大约10,000,000行),如下所示:

import pandas as pd
import numpy as np
col1 = ['A', 'C', 'D', 'D', 'D']
col2 = ['B', 'A', 'B', 'C', 'A']
col3 = [14, 36, 5, 12, 96]
df = pd.DataFrame(np.column_stack([col1, col2, col3]),
                  columns=['col1','col2','col3'])
df['col3'] = df['col3'].astype(int)


  col1 col2  col3
0    A    B    14
1    C    A    36
2    D    B     5
3    D    C    12
4    D    A    96

我想找到与每个唯一词(A,B,C,D)相关联的最小值:

A B 14
D B 5
C D 12
D B 5

我尝试了以下但速度太慢了:

for i in ['A', 'B', 'C', 'D']:
   dm = df.loc[(df['col1'] == i) | (df['col2'] == i)]
   print dm.ix[dm['col3'].idxmin()]

有什么建议吗?

3 个答案:

答案 0 :(得分:5)

您可以使用“熔化”转到长格式并使用groupby.min:

pd.melt(df, id_vars=['col3']).groupby('value')['col3'].min()
Out: 
value
A    14
B     5
C    12
D     5
Name: col3, dtype: int64

答案 1 :(得分:2)

您可以找到两列中每一列的最小值,然后取最小值:

pd.concat([df.groupby('col1').min(), df.groupby('col2').min()], axis=1)\
         .min(axis=1).astype(int)
#A    14
#B     5
#C    12
#D     5

答案 2 :(得分:2)

这与@ DYZ的答案有些相似,尽管我的测试速度要快得多。如果它被认为过于衍生而不能作为单独的答案发布,我很乐意将其删除。

df1 = df.groupby('col1')['col3'].min()
df2 = df.groupby('col2')['col3'].min()
df1.append(df2).groupby(level=0).min()

A    14
B     5
C    12
D     5

我通过简单地将测试数据扩展到10,240行进行测试。在这种情况下,它比其他提议的解决方案快得多,但比@ ayhan的答案慢一点(10%),但也许与其他数据相比,它可能明显更快或更慢。