4

我刚刚开始使用 Pandas,我正在尝试确定它是否是解决我问题的正确工具。

我有一个数据集:

date, sourceid, destid, h1..h12

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

例如:

排除 sourceid = 4944 的 H4、H5、H6 数据,排除目的地 = 481981 的 H8、H9-H12 和 ...

...这可以持续到许多过滤器,因为我们不断删除数据以接近我们的最终模型。

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

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

4

2 回答 2

5

通过使用掩码,您不必从数据框中删除数据。例如:

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

或者直接做:

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

如果有多个过滤器,您可以将布尔掩码与布尔运算符组合:

totmask = mask1 & mask2
于 2013-02-14T08:19:54.073 回答
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 where 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)

查找 10 <= 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) 的掩码数组更快。

于 2013-02-15T03:53:16.580 回答