【问题标题】:Iteration over df rows to sum groups of items迭代 df 行以对项目组求和
【发布时间】:2021-11-17 00:11:12
【问题描述】:

我是编码新手。我在这个网站上寻找了类似的问题,这帮助我想出了我的代码的工作版本,但我需要帮助以使其更专业。

我需要帮助来遍历 pandas 中的数据框行。我想要做的是在“描述”列中找到相同的项目(例如杂货)并从“金额”列中总计(总和)它们的值,最后将结果写入 .csv 文件。我这样做的原因是为了根据这些类别为我想要创建的条形图编译数据。

在以下代码的帮助下,我能够完成所有这些工作,但这很可能不是很 Python 或高效。我所做的是使用嵌套在 if 语句中的 print 语句来获取类别标签 (i) 并打印到文件中。问题是我必须添加很多东西才能使整体工作。首先,我必须创建一个空列表以确保 if 语句不会在每次在“描述”列中看到所需项目时触发 .loc。其次,我不确定保存打印语句是否是最好的方法,因为它看起来很假。感觉就像我离使用打孔卡还有一步之遥。简而言之,如果有人可以帮助我使我的代码更符合标准,我将不胜感激。

'''

used_list = []
for i in df['Description']:
    if i in used_list:
        continue
    sys.stdout = open(file_to_hist, "a")
    print(i,',', df.loc[df['Description'] == i, 'Amount'].sum())
    used_list.append(i)

'''

我还尝试了一种稍微不同的方法(将结果直接保存到 df 中),但随后我在“金额”列中得到了 NaN 值,并且没有其他错误(退出代码 0)来帮助我了解发生了什么:

'''

used_list = []
df_hist_data = pd.DataFrame(columns=['Description', 'Amount'])
for i in df['Description']:
    if i in used_list:
        continue
    df_hist_data = df_hist_data.append({'Description' : i}, {'Amount' : df.loc[df['Description'] == i, 'Amount'].sum()})
    used_list.append(i)

print(df_hist_data)

'''

【问题讨论】:

  • 嗨,我最初读了你的帖子有点快,并认为你希望对一组值求和。我知道您的问题更多是冗余或具有相同 description 值的行。我已经更新了我的答案,希望它适合您的需求。

标签: python pandas dataframe csv iteration


【解决方案1】:

您只能选择符合条件的行 df[ a boolean matrix here ]

在执行df["a column name"]=="value" 时,您实际上会得到一个布尔矩阵,其中"a column name" == "value" 的行是True,其他行是False

总结一下:Dataframe[Dataframe["Description"] == "banana"] 将为您提供一个新数据框的视图,其中仅保留与您的条件匹配的行。 (原始数据框未更改)

如果您选择此数据框的"Amount" 列和.sum() 它,您将在一行中获得所需的内容。 这是典型的 pandadorable(相当于 pandas 的 pythonic)进行条件求和的方式。

如果需要,选择条件可以采用多个值的数据框行,使用.isin() 获取布尔矩阵

Dataframe["Description"].isin(["banana","apple"])

然后,当扫描数据框中所有可能的“描述”值时,在生成迭代器时使用.unique()

然后您最终可以将 Series 附加到您的空数据框,然后将其保存为 csv。

总的来说,我们得到了代码:

import pandas as pd

Dataframe = pd.DataFrame([
    {"Description":"apple","Amount":15},
    {"Description":"banana","Amount":1},
    {"Description":"berry","Amount":155},
    {"Description":"banana","Amount":4}])

df_hist_data = pd.DataFrame(columns=['Description', 'Sum'])

for item in Dataframe["Description"].unique() :
    df_hist_data = df_hist_data.append( pd.Series( 
        { "Description" : item , 
         "Sum" : Dataframe[(Dataframe["Description"].isin([item]))]["Amount"].sum() }
        ), ignore_index=True )

OUT: 
>> 20

你也可以用更 Python 的方式来做,在一行中使用列表理解:


selector = "Description"
sum_on = "Amount"
new_df =  pd.DataFrame([  {selector : item , sum_on : df[(df[selector].isin([item]))][sum_on].sum() } for  item in df[selector].unique() ] )

【讨论】:

  • 感谢您抽出宝贵时间详尽地回答我的问题。
猜你喜欢
  • 1970-01-01
  • 2019-05-02
  • 1970-01-01
  • 2021-09-30
  • 1970-01-01
  • 2021-01-19
  • 2022-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多