【问题标题】:Pandas, how to group and count samples without loop?熊猫,如何在没有循环的情况下对样本进行分组和计数?
【发布时间】:2021-11-28 19:23:02
【问题描述】:

我正在尝试通过对 Stack Overflow 开发人员调查 2021 数据进行数据分析来学习 pandas。可以从https://insights.stackoverflow.com/survey 访问数据。
我的目标是检索每种开发人员类型使用的 5 种最常用的语言。 总而言之,示例的 DevType 如下所示:

 C++;HTML/CSS;JavaScript;Objective-C;PHP;Swift

LanguageHaveWorkedWith 看起来像这样:

Developer, desktop or enterprise applications;Developer, full-stack;Developer, back-end

所以每种语言和类型都用分号(;)分隔。

我通过使用循环实现了这一点。这是我想要的示例输出:

...
Developer, back-end
JavaScript: 72.66%
SQL: 58.62%
HTML/CSS: 56.65%
C#: 46.8%
Python: 40.15%

Developer, front-end
JavaScript: 92.19%
HTML/CSS: 78.91%
SQL: 54.3%
TypeScript: 51.17%
Node.js: 50.39%
...

代码:

from collections import Counter
dev_type_info = {}
for index, row in merged_df.iterrows():
    dev_types = row['dev_type'].split(';')
    for dev_type in dev_types:
        dev_type_info.setdefault(dev_type, {
            'total': 0,
            'language_counter': Counter()
        })
        languages = row['languages'].split(';')
        dev_type_info[dev_type]['language_counter'].update(languages)
        dev_type_info[dev_type]['total'] += 1


for dev_type, info in dev_type_info.items():
    print(dev_type)
    for language, value in info['language_counter'].most_common(5):
        language_pct = (value / info['total']) * 100
        language_pct = round(language_pct, 2)

        print(f'\t{language}: {language_pct}%')

有没有办法使用 pandas 或更短的实现而不是像上面那样的循环来实现这一点?

【问题讨论】:

  • 类似df['dev_type'].str.split(';').explode().groupby(level=0).value_counts(),或df['dev_type'].str.get_dummies(';')

标签: python pandas data-analysis


【解决方案1】:

您需要使用.str.split 将分号分隔的列转换为列表,然后使用pd.explode 将它们展开为单独的行。之后就是数数的问题了:

df['LanguageHaveWorkedWith'] = df['LanguageHaveWorkedWith'].str.split(";")
df['DevType'] = df['DevType'].str.split(";")

tab = df[['DevType','LanguageHaveWorkedWith']].\
explode(['DevType']).explode(['LanguageHaveWorkedWith']).\
value_counts().to_frame("counts")

然后获取每个 DevType 的百分比,请注意,在您的示例中,它们的总和不等于 100%,而这将:

tab = tab.reset_index()
tab['perc'] = 100*tab['counts'] / tab.groupby('DevType')['counts'].transform('sum')

每种开发者类型的前 5 名:

    tab.groupby('DevType').head(5).sort_values('DevType')
 
                  DevType LanguageHaveWorkedWith  counts       perc
234   Academic researcher             Bash/Shell    1065   6.621076
229   Academic researcher                    C++    1114   6.925707
119   Academic researcher                 Python    2090  12.993472
198   Academic researcher             JavaScript    1287   8.001243
212   Academic researcher               HTML/CSS    1179   7.329810

【讨论】:

  • 感谢您的回答。几个注意事项:我在explode(['x'])中遇到错误,所以我将两个explode都更改为explode('x')。我也无法描述 tab['perc'] 为我们提供了什么。将 tab['counts'] 除以每种开发人员类型的总人数,还是每个开发人员使用的总语言数更好?这两者有什么区别?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-29
  • 2021-05-13
  • 2016-02-16
  • 2021-03-31
  • 2018-03-24
  • 1970-01-01
相关资源
最近更新 更多