python - groupby.shift 时的性能问题

标签 python pandas performance pandas-groupby

测试代码:

SIZE_MULT = 5
data = np.random.randint(0, 255, size=10**SIZE_MULT, dtype='uint8')
index = pd.MultiIndex.from_product(
            [list(range(10**(SIZE_MULT-1))), list('ABCDEFGHIJ')],
            names = ['d', 'l'])        
test = pd.DataFrame(data, index, columns = ['data'])
test.head()
test['data'].dtype

输出:

        data
d   l   
0   A   137
    B   156
    C   48
    D   186
    E   170

dtype('uint8')

假设我们想要按索引的 0 级分组并移动每个组(例如,移动步长 = 2)。

%%time
shifted = test.groupby(axis=0, level=[0]).shift(2)
print(shifted['data'].dtype)

输出:

float64
CPU times: user 9.43 ms, sys: 56 µs, total: 9.49 ms
Wall time: 8.29 ms

现在问题来了:如果我们想保留我们的 dtype 'uint8',我们必须摆脱 None,例如,将我们的填充值设置为 0。但是我们现在将获得大量的代码执行时间:

%%time
shifted = test.groupby(axis=0, level=[0]).shift(2, fill_value = 0)
shifted.head()
print(shifted['data'].dtype)

输出:

uint8
CPU times: user 5.9 s, sys: 38.4 ms, total: 5.94 s
Wall time: 5.89 s

所以问题是为什么这么长?如果我们采用没有 fill_value 的第一个移位数据帧,并添加几行代码来获得相同的结果:

%%time
shifted = test.groupby(axis=0, level=[0]).shift(2)
shifted.fillna(0, inplace=True)
shifted = shifted.astype(np.uint8)
print(shifted['data'].dtype)

输出:

uint8
CPU times: user 9.64 ms, sys: 3.68 ms, total: 13.3 ms
Wall time: 11.3 ms

它只会增加几毫秒,而不是 5 秒。

编辑:对应的github issue

最佳答案

来自source code问题是指定的填充值使用缓慢的应用调用。没有填充值,它能够使用更快的 cythonized 结果:

链接中的代码:

def shift(self, periods=1, freq=None, axis=0, fill_value=None):
    #...
    if freq is not None or axis != 0 or not isna(fill_value):
        return self.apply(lambda x: x.shift(periods, freq,
                                            axis, fill_value))

    return self._get_cythonized_result('group_shift_indexer',
                                       self.grouper, cython_dtype=np.int64,
                                       needs_ngroups=True,
                                       result_is_index=True,
                                       periods=periods)

所以在这种情况下,我会在之后使用 .fillna()

关于python - groupby.shift 时的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56043139/

相关文章:

python - 在 Pandas 中按组创建递增的整数系列

iphone - 级联删除大对象图时如何减少核心数据的内存使用?

python - 有什么方法可以返回生成的随机辅音或元音并将其输出为长度为 8 的字符串吗?

python - Pandas 变化指数的优点和缺点

python - 在 python 中显示大型 .dat 二进制文件

python - 在 Python 中使用 Pandas/matplotlib 更改 X 轴标签

python - mongodb findOne 和 $or 参数的顺序重要还是层次结构? [表现]

sql - 有哪些工具可以测试SQL语句的性能?

python - 在Raspberry Pi 3上设置virtualenv和virtualenvwrapper时出现问题

python mmap在写入时跳过第二个字节