有效地查找具有唯一值的pandas(部分)行

时间:2016-09-20 10:09:29

标签: python performance pandas

给定一个pandas数据帧,每个/每个记录行。行包括属性值及其随时间的演变(0到N)。

计划包括以下示例中从第1天到第10天的多个实体的变量“属性”的估计值。

我希望在给定时间内过滤具有唯一值的实体并获取这些值

csv=',property,1,2,3,4,5,6,7,8,9,10\n0,100011,0,0,0,0,3,3,3,3,3,0\n1,100012,0,0,0,0,2,2,2,8,8,0\n2, \
100012,0,0,0,0,2,2,2,2,2,0\n3,100012,0,0,0,0,0,0,0,0,0,0\n4,100011,0,0,0,0,2,2,2,2,2,0\n5, \
180011,0,0,0,0,2,2,2,2,2,0\n6,110012,0,0,0,0,0,0,0,0,0,0\n7,110011,0,0,0,0,3,3,3,3,3,0\n8, \
110012,0,0,0,0,3,3,3,3,3,0\n9,110013,0,0,0,0,0,0,0,0,0,0\n10,100011,0,0,0,0,3,3,3,3,4,0'

from StringIO import StringIO
import numpy as np

schedule = pd.read_csv(StringIO(csv), index_col=0)
print schedule

    property  1  2  3  4  5  6  7  8  9  10
0     100011  0  0  0  0  3  3  3  3  3   0
1     100012  0  0  0  0  2  2  2  8  8   0
2     100012  0  0  0  0  2  2  2  2  2   0
3     100012  0  0  0  0  0  0  0  0  0   0
4     100011  0  0  0  0  2  2  2  2  2   0
5     180011  0  0  0  0  2  2  2  2  2   0
6     110012  0  0  0  0  0  0  0  0  0   0
7     110011  0  0  0  0  3  3  3  3  3   0
8     110012  0  0  0  0  3  3  3  3  3   0
9     110013  0  0  0  0  0  0  0  0  0   0
10    100011  0  0  0  0  3  3  3  3  4   0

我想查找某个属性在给定时间内没有变化的记录/个人以及相应的唯一值

以下是我的意见:我希望在第7天和第10天之间找到[100011,100012,1100012]财产的人

props = [100011, 100012, 1100012]
begin = 7
end = 10

res = schedule['property'].isin(props)
df = schedule.ix[res, begin:end]
print "df \n%s " %df 

我们有:

df 
    7  8  9
0   3  3  3
1   2  8  8
2   2  2  2
3   0  0  0
4   2  2  2
10  3  3  4 

res = df.apply(lambda x: np.unique(x).size == 1, axis=1)
print  "res : %s\n" %res
df_f = df.ix[res,]
print "df filtered  %s \n" % df_f

res = pd.Series(df_f.values.ravel()).unique().tolist()
print "unique values : %s " %res

给予:

res :
 0      True
1     False
2      True
3      True
4      True
10    False
dtype: bool

df filtered 
    7  8  9
0  3  3  3
2  2  2  2
3  0  0  0
4  2  2  2 

unique values : [3, 2, 0] 

由于这些操作需要在一百万行数据帧上运行多次(以百万计),我需要能够尽快运行它。

(@ MaxU):可以将计划视为多次更新的数据库/存储库。然后,对于唯一值,请求存储库多次

您是否对改进/替代方法有一些想法?

1 个答案:

答案 0 :(得分:0)

鉴于你的df

    7  8  9
0   3  3  3
1   2  8  8
2   2  2  2
3   0  0  0
4   2  2  2
10  3  3  4 

您可以将代码简化为:

df_f = df[df.apply(pd.Series.nunique, axis=1) == 1]
print(df_f)
   7  8  9
0  3  3  3
2  2  2  2
3  0  0  0
4  2  2  2

最后一步:

res = df_f.iloc[:,0].unique().tolist()

print(res)
[3, 2, 0]

它没有完全矢量化,但是这可能会澄清一些事情吗?