DataFrame的复杂过滤

时间:2013-02-14 06:30:30

标签: python pandas

我刚刚开始与Pandas合作,我想知道它是否适合我的问题。

我有一个数据集:

date, sourceid, destid, h1..h12

我基本上对每个H1..H12列的总和感兴趣,但是,我需要从数据集中排除多个范围。

例如:

  

排除H4,H5,H6数据,其中sourceid = 4944并排除H8,H9-H12   其中destination = 481981和...

...我们可以继续使用许多过滤器 不断删除数据以接近我们的最终模型。

我想我在一个解决方案中看到我可以构建一个我想要的过滤器列表然后创建一个要测试的函数,但是我还没有找到一个很好的例子。

我最初的想法是创建一个df的副本,然后删除我们不想要的数据,如果我们需要它 - 我们可以将它从原点df复制回来,但这似乎是错误的道路

2 个答案:

答案 0 :(得分:5)

通过使用掩码,您不必从数据帧中删除数据。 E.g:

mask1 = df.sourceid == 4944
var1 = df[mask1]['H4','H5','H6'].sum()

或者直接做:

var1 = df[df.sourceid == 4944]['H4','H5','H6'].sum()

如果是多个过滤器,您可以将布尔蒙版与布尔运算符结合使用:

totmask = mask1 & mask2

答案 1 :(得分:1)

您可以使用DataFrame.ix[]将数据设置为零。

首先创建一个虚拟DataFrame:

N = 10000    
df = pd.DataFrame(np.random.rand(N, 12), columns=["h%d" % i for i in range(1, 13)], index=["row%d" % i for i in range(1, N+1)])
df["sourceid"] = np.random.randint(0, 50, N)
df["destid"] = np.random.randint(0, 50, N)

然后,您可以为每个过滤器调用:

df.ix[df.sourceid == 10, "h4":"h6"] = 0

因为你有600k行,所以df.sourceid == 10创建一个掩码数组可能很慢。您可以创建将值映射到DataFrame的索引的Series对象:

sourceid = pd.Series(df.index.values, index=df["sourceid"].values).sort_index()
destid = pd.Series(df.index.values, index=df["destid"].values).sort_index()

然后排除h4,h5,h6,其中sourceid == 10 by:

df.ix[sourceid[10], "h4":"h6"] = 0

查找sourceid == 10和destid == 20:

的行ID
np.intersect1d(sourceid[10].values, destid[20].values, assume_unique=True)

找到行< = sourceid< = 12和3< = destid< = 5:

的行ID
np.intersect1d(sourceid.ix[10:12].values, destid.ix[3:5].values, assume_unique=True)

sourceid和destid是具有重复索引值的Series,当索引值按顺序排列时,Pandas使用searchsorted查找索引。它是O(log N),然后创建掩码数组,这是O(N)。