【问题标题】:Need to create multiple dataframes in nested for loops based on certain filters需要基于某些过滤器在嵌套的 for 循环中创建多个数据框
【发布时间】:2018-07-26 19:09:26
【问题描述】:

我有证券的主要原始数据,我需要根据某些过滤标准创建多个证券投资组合。我习惯用 C++ 工作,不太清楚如何在 python 中实现以下内容。

我尝试使用嵌套的 for 循环制作不同的数据框:

i - 用于循环从 2007 年到 2017 年(原始数据中的第 yr 列)

j - 用于循环从 1 到 4 的区域(原始数据中的列区域)

for i in range (2007, 2018):
    for j in range (1,5):
         dfij_filter = (df['yr'] == i) & (df['Region'] == j)
         dfij = dfij[dfij_filter]
         dfij = dfij.join(dfco.groupby('ISSUER_NAME')['E_SCORE'].mean(), on = 'ISSUER_NAME', rsuffix = '_ry')
         dfij = dfij.join(dfco.groupby('ISSUER_NAME')['P_SCORE'].mean(), on = 'ISSUER_NAME', rsuffix = '_ry')
         dfij = dfij.join(dfco.groupby('ISSUER_NAME')['Q_SCORE'].mean(), on = 'ISSUER_NAME', rsuffix = '_ry')
         dfij = dfij.drop_duplicates(subset['ISSUER_NAME'], keep=False)
         dfij_E = dfij.sort_values('E_SCORE_ry', ascending = False)
         dfij_ETOP = dfij_E.iloc[:50, :]
         dfij_P = dfij.sort_values('P_SCORE_ry', ascending = False)
         dfij_PTOP = dfij_P.iloc[:50, :]
         dfij_Q = dfij.sort_values('E_SCORE_ry', ascending = False)
         dfij_QTOP = dfij_Q.iloc[:50, :]

我需要创建不同的数据帧,然后在这些数据帧上应用几个函数: 本质上,流程是: 第 1 步:年份过滤器 --> 第 2 步:区域过滤器 --> 第 3 步:计算该年份和地区的平均 E 分值、平均 P 分值、平均 Q 分值 -->(E、P、Q 是不同的列) 第四步:按平均E值降序排列证券--> 第 5 步:挑选前 50 名证券并将它们放入数据框中

对 P 和 Q 分数也重复第 4 步和第 5 步。

本质上是创建 10*4*3 的数据帧。

这些数据框随后可用于回测目的

任何帮助将不胜感激。谢谢

【问题讨论】:

  • 什么不起作用/需要修复?
  • 感谢您的回复约尔格。我不知道如何在嵌套的 for 循环中创建数据框。在上面的代码中,我无法动态创建名称为 dfij 的数据帧(例如,--> df20071)。我知道这可以在字典中完成,但我不确定这里是如何工作的。

标签: python python-3.x pandas dataframe nested


【解决方案1】:

您可以使用字典来存储数据框。这具有启用 O(1) 查找和分组相关数据的额外好处。您不需要为此使用嵌套循环,您可以将dict + groupby 与输入数据框df 一起使用:

dfs = dict(tuple(df.groupby(['yr', 'region']))

这会创建一个字典dfs,将“yr”和“region”的每个组合映射到一个数据框。您可以通过d[(2010, 1)] 访问 2010 年和区域 1 的数据框。

现在要修改您的数据框,您可以像对任何其他字典一样简单地迭代您的字典:

ETOP, PTOP, QTOP = {}, {}, {}

for key in dfs:
    dfs[key] = dfs[key].join(dfco.groupby('ISSUER_NAME')['E_SCORE'].mean(), ...)
    ...
    dfs[key]= dfs[key].drop_duplicates(subset=['ISSUER_NAME'], keep=False)
    ...
    E = dfs[key].sort_values('E_SCORE_ry', ascending = False)
    ETOP[key] = E.head(50)
    ...

请注意,我创建了字典 ETOPPTOPQTOP 来存储结果数据帧,每个都由相同的 ('yr', 'region') 键结构索引。这样,您可以轻松访问、修改或组合任何特定组合的结果。

【讨论】:

  • 感谢 jpp。在线: dfs[key]= dfs[key].drop_duplicates(subset=['ISSUER_NAME'], keep=False) 。无论大小写如何,如何删除重复项?
  • 您可以使用dfs[key] = dfs[key][~dfs[key]['ISSUER_NAME'].str.lower().duplicated()]。有关详细信息,请参阅pd.Series.duplicated
【解决方案2】:
for k, v in df.groupby(['yr', 'region']):
    print(v)

【讨论】:

  • 感谢ZJS的帮助。我需要创建不同的数据帧,然后在这些数据帧上应用一些函数:基本上流程是:Yr filter --> Region filter --> Calc an average E score value for that yr and region --> 按降序排列证券平均 E 分数 --> 挑选前 50 只证券并将它们放入数据框中。然后这些数据框可用于回测目的。
  • 请添加您的代码解释,这将大大提高答案的质量。
猜你喜欢
  • 1970-01-01
  • 2017-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-20
  • 2021-01-13
  • 2016-05-09
相关资源
最近更新 更多