【问题标题】:Pivot Pandas dataframe to see if condition is met透视 Pandas 数据框以查看是否满足条件
【发布时间】:2021-01-27 11:23:46
【问题描述】:

我有以下 DataFrame 表示用户在某周、某年是否存在:

    User    Year    Week
0   John    2020    1
1   John    2020    2
2   Steve   2020    1
3   Fred    2020    3
4   George  2020    2   
5   George  2020    3
    ...     ...     ...
200 John    2021    2
201 John    2021    4
202 Steve   2021    2
203 Fred    2021    2
204 George  2021    1   
205 George  2021    4

我想得到一个 DataFrame,它按User 对数据集进行分组,每一列代表他是否在某一年的某一周出现,每一列的类型要么是布尔型,要么是整数,可能值为 0 或 1。

看起来像这样:

        2020_1  2020_2  2020_3  ... 2021_1  2021_2  2021_3  2021_4
John         1       1       0  ...      0       1       0       1
Steve        1       0       0  ...      0       1       0       0
Fred         0       0       1  ...      0       1       0       0
George       0       1       1  ...      1       0       0       1

有没有在不遍历 DataFrme 的情况下做到这一点?

谢谢。

【问题讨论】:

  • 所有 3 个的解决方案都很棒。我学到了一些新东西。感谢所有 3 个 SO 成员的回答。对所有 3 个问题和问题 +1

标签: python pandas


【解决方案1】:

创建一个新列并使用pd.crosstab

pd.crosstab(df['User'],
            df[['Year','Week']].astype(str).apply('_'.join, axis=1)
           )

输出:

col_0   2020_1  2020_2  2020_3  2021_1  2021_2  2021_4
User                                                  
Fred         0       0       1       0       1       0
George       0       1       1       1       0       1
John         1       1       0       0       1       1
Steve        1       0       0       0       1       0

【讨论】:

  • 对,但是我还是需要根据当年和那周是否有使用来填充对应的值
  • 我不明白,你试过我的代码了吗?你不喜欢它的什么地方?
  • 对不起,也许我没有说清楚:即使“year_week”中没有任何用户,我也希望该列存在。在我的示例中,2021_3 中没有人,但我希望该列存在
  • @Heathcliff 在crosstab 之后探索reindex
【解决方案2】:

这里有一种方法可以做到这一点:

import pandas as pd
df = pd.DataFrame({
    "User" : ["John","John","Steve","Fred","George","George"],
    "Year" : [2020,2020,2020,2020,2020,2020],
    "Week": [1,2,1,3,2,3]})

# add a helper column for year_week
df["year_week"] = df["Year"].map(str) + "_" + df["Week"].map(str)

# group by User and year_week, then unstack and fill NaN with 0
df.groupby(["User","year_week"]).size().unstack(fill_value = 0)

结果:

| User   |   2020_1 |   2020_2 |   2020_3 |
|:-------|---------:|---------:|---------:|
| Fred   |        0 |        0 |        1 |
| George |        0 |        1 |        1 |
| John   |        1 |        1 |        0 |
| Steve  |        1 |        0 |        0 |

【讨论】:

  • 使用unstack(fill_value=0)将保持数据类型为int
  • 嘿!那是涂料@QuangHoang。每天学习新东西。
【解决方案3】:
pd.crosstab(df.User, df['Year'].astype(str)+"_"+df['Week'].astype(str))

【讨论】:

    猜你喜欢
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    • 2019-05-17
    相关资源
    最近更新 更多