【问题标题】:Iterate conditionally and output dataframes and charts有条件地迭代并输出数据框和图表
【发布时间】:2019-07-24 14:36:58
【问题描述】:

我正在尝试为我的每个“vals”输出一个数据框和一个图表。我正在努力拼凑一些 Pythonic 基础知识。

流程:我获取数据框,进行分组,获取总数的百分比...输出表格和图表。但是,我想循环执行此过程,第一次在 Reviewed?=='Yes' 上使用数据帧过滤器,然后在 No 上使用。

data = {'Region': ["US", "US", "US","US"],
        'Gender': ["M","F","F","M"],
        'Reviewed?': ["Yes","Yes","No","No"]}
df = pd.DataFrame(data, columns=['Region','Gender','Reviewed?'])

def func(df):
    vals = ['Yes','No']
    for i in range(len(vals)):
        for x in vals:
            gb[i] = df[df['Reviewed?']==x].groupby(['Gender'])['Region'].count().reset_index()
            total[i] = gb[i]['Region'].sum()
            gb[i]['Percentage'] = (gb[i]['Region'] / total[i])
            gb[i] = gb[i].sort_values(by='Percentage', ascending=False)
            sns.barplot(data=gb[i], x='Region', y='Percentage')
    plt.show()
    return gb[i]

一些错误消息:

ValueError: could not broadcast input array from shape (0,2) into shape (0)

ValueError: cannot copy sequence with size 2 to array axis with dimension 0

ValueError: Cannot set a frame with no defined index and a value that cannot be converted to a Series

更新 这是我想要的蛮力版本。我只是想要一种更高效、更动态的方式来做到这一点。

请注意,我最初并没有明确表示我想将计数保留在最终数据帧中......

import pandas as pd
import seaborn as sns

data = {'Region': ["US", "US", "US","US"],
        'Gender': ["M","F","F","M"],
        'Reviewed?': ["Yes","Yes","No","No"]}
df = pd.DataFrame(data, columns=['Region','Gender','Reviewed?'])

def func(df):
    gb = df[df['Reviewed?']=='No'].groupby(['Gender'])['Region'].count().reset_index()
    total = gb['Region'].sum()
    gb['Percentage'] = (gb['Region'] / total)
    notyetreviewed = gb.sort_values(by='Percentage', ascending=False)
    sns.barplot(data=notyetreviewed, x='Gender', y='Percentage')
    bottom, top = plt.ylim(0,1) 
    plt.show()

    gb = df[df['Reviewed?']=='Yes'].groupby(['Gender'])['Region'].count().reset_index()
    total = gb['Region'].sum()
    gb['Percentage'] = (gb['Region'] / total)
    reviewed = gb.sort_values(by='Percentage', ascending=False)
    bottom, top = plt.ylim(0,1)  
    sns.barplot(data=reviewed, x='Gender', y='Percentage')
    plt.show()

    return notyetreviewed, reviewed
func(df)

【问题讨论】:

  • 您无法在单个代码运行中获得 3 个ValueErrors。它是哪一个?感谢您尝试说明各种尝试
  • 所以,我们这里应该有 2 个图表,每个图表显示 M/F 的 50/50 拆分?
  • ha,显然你在这方面没有我那么糟糕 :) 在第一个值错误之后,我得到:“在处理上述异常期间,发生了另一个异常:”同样的事情发生在第二个值错误。
  • 是的,我只是为可重现的代码添加了一些虚拟数据。
  • 我试图修复您的缩进,因为它在 func 中缩进了很远,请检查并确保它仍然正确。

标签: python pandas for-loop seaborn


【解决方案1】:

你可以试试这样的:

import pandas as pd

data = {'Region': ["US", "US", "US","US"],
        'Gender': ["M","F","F","M"],
        'Reviewed?': ["Yes","Yes","No","No"]}
df = pd.DataFrame(data, columns=['Region','Gender','Reviewed?'])

for outcome in ['Yes', 'No']:
    filtered = df[df['Reviewed?'].eq(outcome)]['Gender'].value_counts(normalize=True)
    filtered.plot.bar()

在这种情况下,我通过 Reviewed? 结果过滤每个循环上的 DF,然后获取男性和女性的比例值。你的问题提出了一个二元选择,但我想它可以通过for outcome in df['Reviewed?'].unique():

【讨论】:

  • 差不多。如前所述,我正在尝试输出图表和数据框。另外,我喜欢保持计数,这就是我手动计算总数的原因。
  • @Christopher 我看不到关于保持计数的问题
  • 当然,我没有专门询问计数,但我将其内置到我的代码中。在这一点上,这真的无关紧要。我特别要求的是输出图表和数据框。感谢您对这段代码的帮助。
【解决方案2】:

这是一个边际改进。很高兴看到一个更 Pythonic 的解决方案,它不需要我将 'Reviewed?' 硬编码到函数调用中......

import pandas as pd
import seaborn as sns

data = {'Region': ["US", "US", "US","US"],
        'Gender': ["M","F","F","M"],
        'Reviewed?': ["Yes","Yes","No","No"]}
df = pd.DataFrame(data, columns=['Region','Gender','Reviewed?'])

def func(df,group,reviewed):
    df = df[df['Reviewed?'].isin(reviewed)].groupby([group])['Region'].count().reset_index()
    df['Percentage'] = df['Region'] / df['Region'].sum()
    sns.barplot(data=df, x='Gender', y='Percentage')
    bottom, top = plt.ylim(0,1)
    plt.show()
    return df

df1 = func(df,'Gender',['Yes'])
df1 = func(df,'Gender',['No'])

【讨论】:

    猜你喜欢
    • 2019-06-30
    • 2022-11-17
    • 2019-07-08
    • 2022-01-02
    • 2019-10-09
    • 1970-01-01
    • 2015-12-18
    • 2021-01-01
    • 1970-01-01
    相关资源
    最近更新 更多