【问题标题】:Python - How do I do conditional counting of rows based on various columns?Python - 如何根据各种列对行进行条件计数?
【发布时间】:2020-02-17 07:07:52
【问题描述】:

我想创建一个 Python 数据框来计算每个样本中每个日期类型 C P 出现的次数. C 和 P 是 F 的子集,这意味着只要 Type 等于 F,我可以计算具有相同 Sample 值的行数,并且相同的日期值。
我无法对条件进行硬编码,因为实际数据集比样本大得多。这意味着我需要将我的条件基于数据集中 Type 等于 F 的值。
这是我的数据集 df_Data 的一个示例(实际更大):

样品 |类型 |日期 |罢工
一个 | F | 2020 年 6 月 1 日 |
一个 | C | 2020 年 6 月 1 日 | 5
一个 |磷 | 2020 年 6 月 1 日 | 2.5
一个 | F | 2020 年 12 月 1 日 |
一个 |磷 | 2020 年 12 月 1 日 | 3
一个 |磷 | 2020 年 12 月 1 日 | 3.5
一个 |磷 | 2020 年 12 月 1 日 | 4
乙| F | 2020 年 6 月 1 日 |
乙| C | 2020 年 6 月 1 日 | 2.5
乙| C | 2020 年 6 月 1 日 | 3
乙| C | 2020 年 6 月 1 日 | 4
乙| F | 2020 年 12 月 1 日 |
乙| C | 2020 年 12 月 1 日 | 2
乙| C | 2020 年 12 月 1 日 | 4
乙|磷 | 2020 年 12 月 1 日 | 2
乙|磷 | 2020 年 12 月 1 日 | 4

对应的输出是一个像这样的新数据框:

样品 |类型 |日期 |数

========================

A | F | 1 Jun 2020 |2
A | F | 1 Dec 2020 |3
B | F | 1 Jun 2020 |3
B | F | 1 Dec 2020 |4  

在 Excel 中,我会使用 CountIfs 函数:
IF Type = "F" then countifs(Sample-column, Sample-value, Date-column, Date-value, Type-column, " F")

请帮忙(为糟糕的表格格式道歉)。

【问题讨论】:

  • 你想如何实现这个?在关系数据库(如 mySQL)中?您正在使用什么(如果有)编程语言?请更新您的标签。
  • 我根据 FoggyDay 的问题做了一些修改。

标签: python dataframe count conditional-statements


【解决方案1】:

我建议以下代码:

import pandas as pd
df = pd.read_csv('sample.csv')
df['Type']=df['Type'].apply(lambda x: 'F' if x == 'P' or 'C' else '')
adf = df.groupby(['Sample', 'Type', 'Dat`enter code here`e'],as_index=False).agg({'Strike':['count']})

此代码将sample.csv 读入数据帧。然后,您对列 Type 执行 lambda 查询。最终结果在adf

【讨论】:

  • 欢迎来到 SO!仅代码的答案可能会被否决或完全删除。我对您的帖子进行了一些编辑,请随时扩展。更多指导,请参考stackoverflow.com/help/how-to-answer
【解决方案2】:

我能够根据@Umesh Sharma 提供的逻辑获得所需的输出。
从原始数据框 df,我创建了一个没有任何 F 行的数据框。

df_no_F = df[df['Type'] != "F"]  

然后我使用 groupby 和 count 来确定每个的行数 样品日期组合。

df_count = df_no_F.groupby(['Sample' , 'Date'], as_index=False).count()

【讨论】:

    【解决方案3】:

    我会这样做。使用df.loc 过滤到所需的类型,然后使用groupbycount :)

    import pandas as pd
    from io import StringIO
    
    # Getting a df in the right form
    s = """Sample | Type | Date | Strike
    A | F | 1 Jun 2020 |
    A | C | 1 Jun 2020 | 5
    A | P | 1 Jun 2020 | 2.5
    A | F | 1 Dec 2020 |
    A | P | 1 Dec 2020 | 3
    A | P | 1 Dec 2020 | 3.5
    A | P | 1 Dec 2020 | 4
    B | F | 1 Jun 2020 |
    B | C | 1 Jun 2020 | 2.5
    B | C | 1 Jun 2020 | 3
    B | C | 1 Jun 2020 | 4
    B | F | 1 Dec 2020 |
    B | C | 1 Dec 2020 | 2
    B | C | 1 Dec 2020 | 4
    B | P | 1 Dec 2020 | 2
    B | P | 1 Dec 2020 | 4"""
    df = pd.DataFrame(pd.read_csv(StringIO(s), sep='|'))
    df.columns = [i.strip() for i in df.columns]
    for col in ['Sample', 'Type', 'Date']:
        df[col] = df[col].str.strip()
    
    # Meat and bones of this operation
    new_df = df.loc[(df['Type'] == 'C') | (df['Type'] == 'P')].groupby(['Sample', 'Date'])['Strike'].count().reset_index()
    
    # Reformat to desired output
    new_df['Type'] = 'F'
    new_df = new_df[df.columns].rename(columns={'Strike': 'Count'}).sort_values(by=['Sample', 'Date'], ascending=[True, False])
    print(new_df)
    

    输出:

      Sample Type        Date  Count
    1      A    F  1 Jun 2020      2
    0      A    F  1 Dec 2020      3
    3      B    F  1 Jun 2020      3
    2      B    F  1 Dec 2020      4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      • 2013-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多