熊猫groupby-apply:无法从重复的轴重新索引

时间:2019-03-15 21:30:38

标签: pandas join

我正在对DataFrame执行groupby操作。在每个组上,我都必须重命名两列并删除一列,以便每个组具有以下形式:

index(timestamp) | column-x | column-y
...              |  ....    | ..... 

索引是一个时间戳,它对于每个组都是通用的。相反,“ column-x”和“ column-y”将对每个组都不同。然后,我的目标是加入索引上的所有组,以便拥有唯一的DataFrame,例如:

index(timestamp) | column-x1 | column-y1 | column-x2 | column-y2 | ...
...              |  .....    | ......    |  .......  | .......   | ...

我应用于每个组的功能是(可以在迭代时对组进行就地编辑吗?):

def process_ssp(df_ssp):
    sensor_name = df_ssp.iloc[0]['subsystem-sensor-parameter'] # to be used as column name
    df_ssp.rename(columns = {
        'value_raw': '%s_raw' % sensor_name,
        'value_hrf': '%s_hrf' % sensor_name,
    }, inplace = True)
    df_ssp.drop('subsystem-sensor-parameter', axis='columns', inplace=True) # since this is the column I am grouping on I guess this isn't the right thing to do?
    return df_ssp

然后我打电话:

res = df_node.groupby('subsystem-sensor-parameter', as_index=False).apply(process_ssp)

哪个会产生错误:

ValueError: cannot reindex from a duplicate axis

编辑: 数据集示例https://drive.google.com/file/d/1RvPE1t3BmjeaqCNkVqGwmokCFQQp77n8/view?usp=sharing

2 个答案:

答案 0 :(得分:1)

您可以首先为MultiIndex添加subsystem-sensor-parameter列,通过unstack重塑形状,按第二级对MultiIndex进行排序,并调整其位置。最后通过使用mapjoin展平来转换MultiIndex:

res = (df_node.set_index('subsystem-sensor-parameter', append=True)
                          .unstack()
                          .sort_index(axis=1, level=1)
                          .swaplevel(0,1, axis=1)) 
res.columns = res.columns.map('_'.join)

答案 1 :(得分:1)

我可以通过遍历组而不是使用apply来成功地应用代码并产生所需的输出:

import pandas as pd
df = pd.read_csv('/Users/jeffmayse/Downloads/sample.csv')
df.set_index('timestamp', inplace=True)

def process_ssp(df_ssp):
    sensor_name = df_ssp.iloc[0]['subsystem-sensor-parameter'] # to be used as column name
    df_ssp.rename(columns = {
        'value_raw': '%s_raw' % sensor_name,
        'value_hrf': '%s_hrf' % sensor_name,
    }, inplace = True)
    df_ssp.drop('subsystem-sensor-parameter', axis='columns', inplace=True) # since this is the column I am grouping on I guess this isn't the right thing to do?
    return df_ssp

groups = df.groupby('subsystem-sensor-parameter')
out = []
for name, group in groups:
    try:
        out.append(process_ssp(group))
    except:
        print(name)
pd.concat(out).shape

Out[7]: (16131, 114)

实际上,问题出在apply方法中,因为不需要您的函数来产生错误:

df.groupby('subsystem-sensor-parameter', as_index=False).apply(lambda x: x)

也计算为ValueError: cannot reindex from a duplicate axis

但是,此语句的评估结果符合我们的预期:

df.reset_index(inplace=True)
df.groupby('subsystem-sensor-parameter', as_index=False).apply(process_ssp)

Out[22]: 
      nc-devices-alphasense_hrf  ... wagman-uptime-uptime_raw
0                             0  ...                      NaN
1                           NaN  ...                      NaN
2                           NaN  ...                      NaN
3                           NaN  ...                      NaN
...

问题是您的DatetimeIndex值重复。 .apply试图将结果集重新组合在一起,但是不确定如何将索引与重复值组合在一起。至少,我相信就是这样。重置索引,然后重试。

编辑:展开,尝试重新为DatetimeIndex编制索引时通常会看到此错误,即您有一个每小时的索引,并希望将其转换为第二个分辨率索引,或者通常填写缺少的小时数。您使用reindex,但是如果您的索引具有重复值,它将失败。我猜这就是这里发生的情况:所应用的函数所产生的数据帧具有重复的索引值,并且该错误来自尝试通过对具有重复项的DatetimeIndex调用reindex来尝试产生输出。重置索引之所以可行,是因为您的索引现在都是唯一的,并且timestamp列对此操作并不重要。