如何解决pandas bug / feature?

时间:2013-02-13 03:57:20

标签: python pandas

我有一只以这种方式创建的大熊猫DataFrame

import pandas as pd
wb = pd.io.parsers.ExcelFile('/path/to/data.xlsx')
df = wb.parse(wb.sheet_names[0])

结果数据框有大约十二列,所有列都具有完全相同的长度(约150K)。

对于大多数列,以下操作几乎是瞬时的

aset = set(df.acolumn)

但是对于某些列来说,操作相同,例如

aset = set(df.weirdcolumn)

采取> 10分钟! (或者说,操作无法在10分钟超时期限到期之前完成。)相同数量的元素!

陌生人仍然:

In [106]: set([type(c) for c in df.weirdcolumn])
Out[106]: set([numpy.float64])

In [107]: df.weirdcolumn.value_counts()
Out[107]: []

该列的内容似乎都是nan s

In [118]: all(np.isnan(df.weirdcolumn.values))
Out[118]: True

但这并不能解释之前提到的减速,因为以下操作只需几秒钟:

In [121]: set([np.nan for _ in range(len(data))])
Out[121]: set([nan])

我已经没有办法找出上面提到的大幅减速的原因。建议欢迎。

1 个答案:

答案 0 :(得分:4)

关于nans的一个奇怪的事情是他们没有比较平等。这意味着将为组分别插入“不同的”nan对象:

>>> float('nan') == float('nan')
False
>>> float('nan') is float('nan')
False
>>> len(set([float('nan') for _ in range(1000)]))
1000

np.nan的测试不会发生这种情况,因为它一遍又一遍地是同一个对象:

>>> np.nan == np.nan
False
>>> np.nan is np.nan
True
>>> len(set([np.nan for _ in range(1000)]))
1

这可能是你的问题;你正在制作150,000个元素集,其中每个元素具有完全相同的散列(hash(float('nan')) == 0)。这意味着将新的nan插入到已经n nans的集合中至少需要O(n)次,因此构建一组N nans至少需要O(N^2)次。 150k ^ 2是......大。

所以是的,Nans很糟糕。您可以通过执行类似

的操作来解决此问题
nan_idx = np.isnan(df.weirdcolumn)
s = set(df.weirdcolumn[~nan_idx])
if np.any(nan_idx):
    s.add(np.nan)