【问题标题】:python pandas - how can I map values in 1 dataframe to indices in another without looping?python pandas - 如何在不循环的情况下将 1 个数据帧中的值映射到另一个数据帧中的索引?
【发布时间】:2017-02-28 04:32:19
【问题描述】:

我有 2 个数据框 - “df_rollmax”是具有相同形状的“df_data”的派生词。我正在尝试将 df_rollmax 的值映射回 df_data 并创建第三个 df (df_maxdates),其中包含 df_rollmax 中的每个值最初出现在 df_data 中的日期。

list1 = [[21,101],[22,110],[25,113],[24,112],[21,109],[28,108],[30,102],[26,106],[25,111],[24,110]]
df_data = pd.DataFrame(list1,index=pd.date_range('2000-1-1',periods=10, freq='D'), columns=list('AB'))
df_rollmax = pd.DataFrame(df_data.rolling(center=False,window=5).max())
mapA = pd.Series(df_data.index, index=df_data['A'])

从上一个问题中,我看到可以通过以下方式找到一个日期:

mapA[rollmax.ix['j','A']] 返回Timestamp('2000-01-07 00:00:00')

但我的真实数据集要大得多,我想用日期填充第三个数据框,而不是遍历每一行和每一列。

映射回索引是一个问题,因为:ValueError: cannot reindex from a duplicate axis 所以这不起作用...

df_maxdates = pd.DataFrame(index=df_data.index, columns=df_data.columns)
for s in df_data.columns:
    df_maxdates[s] = mapA.loc[df_rollmax[s]]

使用重复值的最后一个实例很好,但df.duplicated(keep='last') 不合作。

非常感谢任何和所有的智慧。

Link to original question

更新 - 这是 df_maxdates 的样子:

【问题讨论】:

  • 你能发布/显示你想要的数据集吗?
  • MaxU - 见上文。谢谢!

标签: python pandas dataframe duplicates mapping


【解决方案1】:

你可以使用this BrenBarn's solution:

W = 5  # window size

df = pd.DataFrame(columns=df_data.columns, index=df_data.index[W-1:])

for col in df.columns.tolist():
    df[col] = df_data.index[df_data[col].rolling(W)
                                    .apply(np.argmax)[(W-1):]
                                    .astype(int)
                             +
                             np.arange(len(df_data)-(W-1))]

df = pd.DataFrame(columns=df_data.columns, index=df_data.index[:W-1]).append(df)

In [226]: df
Out[226]:
                    A          B
2000-01-01        NaT        NaT
2000-01-02        NaT        NaT
2000-01-03        NaT        NaT
2000-01-04        NaT        NaT
2000-01-05 2000-01-03 2000-01-03
2000-01-06 2000-01-06 2000-01-03
2000-01-07 2000-01-07 2000-01-03
2000-01-08 2000-01-07 2000-01-04
2000-01-09 2000-01-07 2000-01-09
2000-01-10 2000-01-07 2000-01-09

this piRSquared's solution:

def idxmax(s, w):
    i = 0
    while i + w <= len(s):
        yield(s.iloc[i:i+w].idxmax())
        i += 1

x = pd.DataFrame({'A':[np.nan]*4 + list(idxmax(df_data.A, 5)),
                  'B':[np.nan]*4 + list(idxmax(df_data.B, 5))},
                 index=df_data.index)

演示:

In [89]: x = pd.DataFrame({'A':pd.to_datetime([np.nan]*4 + list(idxmax(df_data.A, 5))),
    ...:                   'B':pd.to_datetime([np.nan]*4 + list(idxmax(df_data.B, 5)))},
    ...:                  index=df_data.index)
    ...:

In [90]: x
Out[90]:
                    A          B
2000-01-01        NaT        NaT
2000-01-02        NaT        NaT
2000-01-03        NaT        NaT
2000-01-04        NaT        NaT
2000-01-05 2000-01-03 2000-01-03
2000-01-06 2000-01-06 2000-01-03
2000-01-07 2000-01-07 2000-01-03
2000-01-08 2000-01-07 2000-01-04
2000-01-09 2000-01-07 2000-01-09
2000-01-10 2000-01-07 2000-01-09

【讨论】:

  • 非常好的 MaxU。可以对更大的数据集使用相同的解决方案,而这不允许我为数据框手动创建字典?
  • 换句话说,如果我有 500 列而不是只有“A”和“B”,有没有办法应用相同的功能?
猜你喜欢
  • 2017-04-20
  • 2022-01-24
  • 2023-03-15
  • 2021-03-26
  • 1970-01-01
  • 1970-01-01
  • 2017-04-06
  • 2020-03-13
  • 1970-01-01
相关资源
最近更新 更多