【问题标题】:Pandas groupby-apply: cannot reindex from a duplicate axisPandas groupby-apply:无法从重复的轴重新索引
【发布时间】:2019-08-07 00:35:41
【问题描述】:

我正在对 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

【问题讨论】:

  • 你能提供带有'subsystem-sensor-parameter'列的源表吗?
  • 是的,我用示例更新了上面的帖子。
  • @shadowtalker 你能解释一下你遇到问题的代码部分吗?你的实际问题与这个问题、代码或数据有什么关系吗?

标签: pandas join


【解决方案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)

【讨论】:

  • 这个函数完成没有错误,但它并没有完全达到我想要的。 res 变量是一个 DataFrame,其索引属于这种类型:('nc-devices-alphasense', Timestamp('2019-03-05 00:02:40'))。这会产生大量的 NaN 值。相反,我只想在索引值上有时间戳。我怎样才能做到这一点?通过在 process_ssp() 中打印 df_ssp,我可以看到 df_ssp 具有我需要的格式。但是, res 并没有按照我的意愿加入加入组,因为它更改了将子系统传感器参数添加到时间戳的索引。
  • @user1315621 - 缺少值是预期的输出,因为在 DataFrame 中,如果某些组没有匹配的填充 NaN,那么只有匹配的组按日期归档,另一个没有。
  • 太棒了!最后一条评论是我要找的。如果您想将其写为答案而不是评论,我将批准它作为正确答案。我会努力理解它是如何工作的;)谢谢!
【解决方案2】:

我能够通过迭代组而不是使用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 时通常会看到此错误,即您有一个每小时索引并希望将其转换为第二个分辨率索引,或者通常填写缺失的小时数。您使用重新索引,但如果您的索引具有重复值,它将失败。我猜这就是这里发生的事情:正在应用的函数生成的数据帧具有重复的索引值,并且错误来自尝试通过在具有重复项的 DatetimeIndex 上调用 reindex 来生成输出。重置索引有效,因为您的索引现在都是唯一的,而 timestamp 列对于此操作并不重要。

【讨论】:

  • 很遗憾,我无法通过两个简单的示例重现该错误:data = pd.DataFrame({'a': [1,2,3,4,5], 'b': [11,11,11,12,12]}, index=['q','r','r','r','t'])data.index = pd.to_datetime(['2019-03-01', '2019-03-04', '2019-03-04', '2019-03-04', '2019-05-12']) 也是如此。尝试.groupby(level=0)/.groupby('b').apply() 中的各种功能的所有组合,例如删除列,这会导致各种重复索引的情况,并且似乎不会导致问题。
  • 我很想将此称为 Pandas 错误并提交报告。这当然不是一个有用的错误。
  • @shadowtalker 我认为这不是一个错误。您能告诉我们您的代码的哪一部分遇到问题吗?
  • @anky_91 忘记我的代码。我的评论的重点是,我无法使用他们描述的推理重现此答案中描述的问题,因此该数据(或该特定函数)中显然还有其他东西触发了错误
  • 我不认为你的例子中的索引和你的真实数据是一样的。如果您向下跟踪堆栈跟踪,您的数据需要使用 pandas._libs.index.IndexEngine.get_indexer_non_unique 方法,而您的示例代码不需要。可以说您的真实数据有一​​个导致某些问题的复杂索引。我仍在尝试调试解决问题的方法,但......要清楚,问题似乎是单独使用timestamp,因为它会导致与str 类型相同的错误。
猜你喜欢
  • 2020-05-23
  • 2018-02-02
  • 1970-01-01
  • 1970-01-01
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-09
  • 2015-02-26
相关资源
最近更新 更多