有没有更有效的方法来检查DataFram行中是否存在值

2024-09-25 16:24:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一组名称UniqueNames和一个Pandas数据帧NamesOverTime,每行都有一个名称列表。我想获得一个序列,指示名称是否包含在特定的行/日期中。下面的代码运行得非常好,但似乎相当慢。有什么办法提高绩效吗?在

for index, row in UniqueNames.iterrows():  
    IndSeries = (NamesOverTime==row['Name']).any(axis=1)

例如:

^{pr2}$

所以名字在数据帧中是任意顺序的。在

我的实际数据集更大,但不是massiv。我有一组大约4000个名字和一个数据帧T=300(行)和N=3000(列)

编辑:预期的输出是UniqueNames中包含的每个名称的Pandas系列对象。我能得到的最快的答案是这样的东西,但它仍然比原来的版本慢3倍左右。在

NamesOTStack = NamesOverTime.stack()
NamesOTStack = NamesOTStack.reset_index(1)

for index, row in UniqueNames.iterrows():
    temp = NamesOTStack[NamesOTStack.loc[:,0]==row['Name']] 
    IndSeries = pd.Series(NamesOverTime.index.isin(temp.index))
    IndSeries.index = NamesOverTime.index

IndSeriesIndSeries看起来像:

IndSeries
Out[16]: 
2015-05-31     True
2015-06-30    False
2015-07-31    False
Freq: M, dtype: bool

Tags: 数据namein名称pandasforindex名字
1条回答
网友
1楼 · 发布于 2024-09-25 16:24:23

编辑:你已经改变了你的输入结构,这是非常重要的,需要一个不同的答案。不管怎样,还是这样。我已经创建了一个数据帧,其中有3000个名字从4000个中随机选择出来,没有在365行中进行替换。在

name_time_pairs = NamesOverTime.unstack().dropna()
name_time_pairs.name = 'name'
name_time_pairs = name_time_pairs.reset_index().iloc[:, 1:]
name_time_pairs['value'] = True

In [104]: name_time_pairs[:2]

Out[104]:
    time        name    value
0   2015-01-01  ypac    True
1   2015-01-02  fjnq    True

到目前为止,我们有一个DataFrame,其中每个time-name对有一行,还有一列包含True,总共1098000行。现在需要做的就是透视表并用False填充空值。在

^{pr2}$

如果你能证明这比循环遍历4000个名字慢,并且在每个循环中扫描原始数据帧慢,我就吃了我的帽子。我的速度快100倍。在

你应该把这个解决方案分解,看看每个步骤是如何工作的,因为它非常简洁,我已经花了太多时间来回答这个问题。这也相当复杂,因为结果的结构,我认为,是不寻常的。基本上你所拥有的是一组时间-名称对。在我看来,将这些存储为布尔型数据帧的索引和列标签是低效的,也许可以用另一种方法来实现。在

相关问题 更多 >