pandas groupby 复数处理失败

2 投票
1 回答
642 浏览
提问于 2025-04-18 01:04

更新:这里是一个简化版的代码(应要求提供),它产生了相同的错误:

import numpy as np
line = [0,0,0,1,1,1,3,3,3,4,4,4]
x = [0,0,0,0,0,0,1,1,1,1,1,1]
y = [0,0,0,1,1,1,0,0,0,1,1,1]
number = np.arange(0, 120, 10)
cnumber = number +1j*0
FrData = [line, x, y, cnumber]
import pandas as pd
ToProcess = pd.DataFrame(data = zip(*(FrData)), index = FrData[0],
                         columns = ['line', 'x', 'y', 'cnumber'])
CleanData = ToProcess.groupby(['line', 'x', 'y'])['cnumber'].mean().reset_index()

这个代码可以运行,但给我报了一个错误——数据不再是复数了:

/usr/lib64/python2.7/site-packages/pandas/core/nanops.py:496: ComplexWarning: 将复数值转换为实数会丢失虚部 x = float(x)

这个错误指向了pandas代码的那部分:

def _ensure_numeric(x):
if isinstance(x, np.ndarray):
    if x.dtype == np.object_:
        x = x.astype(np.float64)
elif not (com.is_float(x) or com.is_integer(x)):
    try:
        x = float(x)
    except Exception:
        raise TypeError('Could not convert %s to numeric' % str(x))

return x

我知道,x.astype(np.complex)这一部分缺失了——我记得在之前的某个pandas版本中,我根据一个帖子修改过这个,但现在找不到那个帖子了——我需要把它加上,这样就不会把我的复数转换回浮点数了——有什么建议吗?

更新 一个临时解决方案是修改nanops.py中上面描述的函数,把x=float(x)替换成x=x.astype(np.complex),这样代码的那部分现在是:

def _ensure_numeric(x):
    if isinstance(x, np.ndarray):
        if x.dtype == np.object_:
            x = x.astype(np.float64)
    elif not (com.is_float(x) or com.is_integer(x)):
        try:
            x = x.astype(np.complex)
        except Exception:
            raise TypeError('Could not convert %s to numeric' % str(x))

    return x

这个方法对我有效,但我不确定这是否是一个正确或完整的解决方案。

1 个回答

0

你可能想要获取复数的实部(也就是用numpy.real这个函数),不过不幸的是,这个操作和pandas的Series或DataFrame配合起来不是特别顺利,所以你需要把索引再应用回去:

In [11]: s = pd.Series([1 + 1j])

In [12]: s
Out[12]:
0    (1+1j)
dtype: complex128

In [13]: np.real(s)
Out[13]:
array([ 1.])

In [14]: pd.Series(np.real(s), s.index, name=s.name)
Out[14]:
0    1
dtype: float64

撰写回答