【问题标题】:Looping through a python dictionary and manipulate each value循环遍历 python 字典并操作每个值
【发布时间】:2019-09-02 09:51:57
【问题描述】:

我是一个相当新的 python 用户,但我遇到了一个问题。任何指导将不胜感激。

我有一个 pandas 数据框,其中包含“ID”、“Intervention”和“GradeLevel”三列。见以下代码:

 data = [[100,'Long', 0], [101,'Short', 1],[102,'Medium', 2],[103,'Long', 0],[104,'Short', 1],[105,'Medium', 2]]

intervention_df = pd.DataFrame(data, columns = ['ID', 'Intervention', 'GradeLevel'])

然后,我创建了一个按“干预”分组的数据框字典。见以下代码:

intervention_dict = {Intervention: dfi for Intervention, dfi in df.groupby('Intervention')}

我的问题是你能遍历字典的值并操作字典的每个值吗?具体来说,我试图引用一个查找表。查找表可以被认为是一个花名册。我的目标是将名册中的任何人标记为“是 - 干预名称”或“否干预”。这变得很棘手,例如,假设 Long Intervention 只有 GradeLevel 0。这意味着我想将 intervention_df 中等级为 0 的任何人标记为“Yes - Long”,而将任何不在 intervention_df 中的人标记为“No - Long” ' 这将成为一个名为 'Value' 的新列。我还需要创建另一个变量“Category”,在此示例中指定干预名称,它只是“Long”

lookup_data = [[100, 0], [101, 1],[102, 2],[103, 0],[104, 1],[105, 2], [106, 0], [107, 0],[108, 2],[109, 1]]
lookup_df = pd.DataFrame(lookup_data, columns = ['ID', 'GradeLevel'])

例如,“Long”字典在处理后将如下所示:

longint_data = [[100,'Long', 'Yes - Long'],[103,'Long', 'Yes - Long'], [106,'Long', 'No - Long'], [107,'Long', 'No - Long']]
longint_df = pd.DataFrame(longint_data, columns = ['ID','Category', 'Value'])

所有操作后所需的最终输出如下所示:

result_data = [[100,'Long', 'Yes - Long'] , [101,'Short','Yes - Short'], [102,'Medium','Yes - Medium'], [103,'Long', 'Yes - Long'], [104,'Short','Yes - Short'] , [105, 'Medium','Yes - Medium'], [106,'Long', 'No - Long'], [107,'Long', 'No - Long'], [108,'Medium','No - Medium'], [109,'Short','No - Short']]

result_df = pd.DataFrame(result_data, columns = ['ID','Category', 'Value'])

谢谢!

【问题讨论】:

  • 看起来你让这变得比它需要的更复杂,我对所有循环和不同的数据帧感到困惑。为什么不只是一个连接?
  • 哎呀,我忘了解释一个部分。对于每次干预,我只想对同年级的人说“不”。例如,Long 干预只有 0 级,因此我只想与具有 0 级的人合并。我忘记将过滤 lookup_df 的步骤添加到该特定干预中的唯一等级。
  • 仍然很混乱。您的结果数据框中有 109, 'Short', 'No - Short' 之类的东西,但没有其他地方引用 109, 'Short'109 本身在lookup_df 中被引用,但没有提及Short
  • 我编辑了我最初的问题,对lookup_df 做了更多解释。这是一个名册。因此,假设您只针对学校的幼儿园学生进行干预。我想列出干预中的学生名单,并将其与整个班级名册进行比较。如果学生在干预中,他们将被标记为“是”,如果他们不在干预中,他们将被标记为“否”。

标签: python pandas loops dataframe dictionary


【解决方案1】:

这就是我觉得你想要的......但没有更清楚的解释,我不确定。

data = [[100,'Long', 0], [101,'Short', 1],[102,'Medium', 2],[103,'Long', 0],[104,'Short', 1],[105,'Medium', 2]]
intervention_df = pd.DataFrame(data, columns = ['ID', 'Intervention', 'GradeLevel'])

lookup_data = [[100, 0], [101, 1],[102, 2],[103, 0],[104, 1],[105, 2], [106, 0], [107, 0],[108, 2],[109, 1]]
lookup_df = pd.DataFrame(lookup_data, columns = ['ID', 'GradeLevel'])


df= pd.merge(intervention_df.assign(y='Yes'), lookup_df, on=['ID', 'GradeLevel'], how='outer')
df.loc[df.y.isnull(), 'y'] = 'No'


    ID Intervention  GradeLevel    y
0  100         Long           0  Yes
1  101        Short           1  Yes
2  102       Medium           2  Yes
3  103         Long           0  Yes
4  104        Short           1  Yes
5  105       Medium           2  Yes
6  106          NaN           0   No
7  107          NaN           0   No
8  108          NaN           2   No
9  109          NaN           1   No

【讨论】:

    【解决方案2】:

    这里是不使用字典intervention_dict 的解决方案。以下是我从您的命令中获得的数据:

    In [1048]: intervention_df
    Out[1048]:
        ID Intervention  GradeLevel
    0  100         Long           0
    1  101        Short           1
    2  102       Medium           2
    3  103         Long           0
    4  104        Short           1
    5  105       Medium           2
    
    In [1049]: lookup_df
    Out[1049]:
        ID  GradeLevel
    0  100           0
    1  101           1
    2  102           2
    3  103           0
    4  104           1
    5  105           2
    6  106           0
    7  107           0
    8  108           2
    9  109           1
    

    步骤 1:在 lookup_dfintervention_df 之间进行外部合并,创建列 Valueset_indexGradeLevel

    In [1059]: df = lookup_df.merge(intervention_df, on=['ID', 'GradeLevel'], how='outer').assign(Value='Yes - '+intervention_df['Intervention']).set_index('GradeLevel')
    
    In [1060]: df
    Out[1060]:
                 ID Intervention         Value
    GradeLevel
    0           100         Long    Yes - Long
    1           101        Short   Yes - Short
    2           102       Medium  Yes - Medium
    0           103         Long    Yes - Long
    1           104        Short   Yes - Short
    2           105       Medium  Yes - Medium
    0           106          NaN           NaN
    0           107          NaN           NaN
    2           108          NaN           NaN
    1           109          NaN           NaN
    

    Step2:创建df_fillna,将NaN填入df

    In [1063]: df_fillna = intervention_df.groupby('Intervention').head(1).assign(Value='No - '+intervention_df['Intervention']).set_index('GradeLevel')
    
    In [1064]: df_fillna
    Out[1064]:
                 ID Intervention        Value
    GradeLevel
    0           100         Long    No - Long
    1           101        Short   No - Short
    2           102       Medium  No - Medium
    

    第 3 步(最终):使用 combine_firstNaNdf_fillna 值填充到 df 并使用 reset_index 删除 'GradeLeveland doingsort_valuesonID `

    In [1068]: df.combine_first(df_fillna).sort_values('ID').reset_index(drop=True)
    Out[1068]:
        ID Intervention         Value
    0  100         Long    Yes - Long
    1  101        Short   Yes - Short
    2  102       Medium  Yes - Medium
    3  103         Long    Yes - Long
    4  104        Short   Yes - Short
    5  105       Medium  Yes - Medium
    6  106         Long     No - Long
    7  107         Long     No - Long
    8  108       Medium   No - Medium
    9  109        Short    No - Short
    

    【讨论】:

      猜你喜欢
      • 2013-11-29
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2022-09-22
      • 1970-01-01
      • 2020-03-04
      • 2014-06-29
      • 1970-01-01
      相关资源
      最近更新 更多