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

时间:2015-05-28 08:43:46

标签: python pandas

我有一组名称UniqueNames和一个Pandas DataFrame NamesOverTime,每行都有一个名称列表。我想获得一个系列,表明该名称是否包含在特定的行/日期。以下代码完美无缺,但似乎很慢。任何想法如何改善性能?

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

一个例子可能是:

 UniqueNames = DataFrame({'Name': ('hello1', 'hello2', 'hello3', 
                        'hello4', 'ciao5')})
 NamesOverTime = DataFrame( {'1': ('hello1', 'hello2', 'hello3', 'hello4'), 
                             '2': ('hello1', 'hello2', 'hello3', NaN), 
                             '3': ('hello3', 'hello1', 'ciao5', NaN)})

 NamesOverTime = NamesOverTime.transpose()
 NamesOverTime.index = pd.date_range('2015-05-31', periods=3, freq='M')

因此,数据框中的名称属于arbirtrary顺序。

我的实际数据集大小更大,但不是质量。我有一组大约4000个名称和一个Dataframe 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
IndSeries的{​​p> 'hello4'如下所示:

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

1 个答案:

答案 0 :(得分:2)

编辑:您已经改变了输入的结构,这非常重要,并且需要不同的答案。无论如何,这里去了。我创建了一个数据框,其中有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,每个时间对都有一行,一行包含True,总共1,098,000行。现在需要做的就是转动表并用False填充空值。

result = name_time_pairs.pivot(index='time', columns='name', values='value').fillna(False)

如果你可以证明这比循环浏览4000个名字要慢并且扫描每个循环中的原始数据框慢,我会吃掉我的帽子。我的速度提高了100倍。

你应该打破这个解决方案,看看每个步骤是如何工作的,因为它非常简洁,而且我已经花了太多时间来回答这个问题。它也很复杂,因为我认为结果的结构是不寻常的。基本上你拥有的是一组时间名称对。将这些作为布尔数据框的索引和列标签存储在我看来效率低下,也许可以用另一种方式完成。

相关问题