迭代 df 行以对项目组求和
Iteration over df rows to sum groups of items
我是编码新手。我在这个网站上寻找过类似的问题,这帮助我提出了我的代码的工作版本,但我需要帮助使其更专业。
我需要帮助来遍历 pandas 中数据框的行。我想要做的是在 'Description' 列中找到相同的项目(例如杂货),并从 'Amount' 列中总计(求和)它们的值,最后将结果写入 .csv 文件。我做这一切的原因是为我想根据这些类别创建的条形图编译数据。
我能够在以下代码的帮助下完成所有这些,但这很可能不是很 pythonic 或高效。我所做的是,我使用嵌套在 if 语句中的打印语句来获取类别标签 (i) 和打印到文件的金额。问题是我必须添加很多东西才能使整体正常工作。首先,我必须创建一个空列表以确保 if 语句不会在每次看到 'Description' 列中的所需项目时触发 .loc。其次,我不确定保存打印语句是否是最好的方法,因为它看起来很 ersatz。感觉离使用打卡又差了一步。简而言之,如果有人可以帮助我使我的代码更符合标准,我将不胜感激。
'''
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 中),但随后我在 'Amount' 列中得到了 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)
'''
您可以 select 只有符合条件的行
df[ a boolean matrix here ]
当执行 df["a column name"]=="value"
时,您实际上得到一个布尔矩阵,其中 "a column name"
== "value"
的行是 True
,其他行是 False
总结一下:Dataframe[Dataframe["Description"] == "banana"] 将为您提供一个新数据框的视图,其中只保留符合您条件的行。 (原始数据框未更改)
如果你 select 这个数据框的 "Amount"
列和 .sum()
它,你就得到了你想要的,在一行中。
这是典型的 pandadorable
(相当于 pythonic
for pandas)进行条件求和的方法。
如果需要,select 条件可以取多个值的数据框行,使用 .isin()
获取布尔矩阵
Dataframe["Description"].isin(["banana","apple"])
然后,在扫描数据框中“Description”的所有可能值时,在生成迭代器时使用 .unique()
。
然后您最终可以将系列附加到您的空数据框,然后再将其保存为 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() ] )
我是编码新手。我在这个网站上寻找过类似的问题,这帮助我提出了我的代码的工作版本,但我需要帮助使其更专业。
我需要帮助来遍历 pandas 中数据框的行。我想要做的是在 'Description' 列中找到相同的项目(例如杂货),并从 'Amount' 列中总计(求和)它们的值,最后将结果写入 .csv 文件。我做这一切的原因是为我想根据这些类别创建的条形图编译数据。
我能够在以下代码的帮助下完成所有这些,但这很可能不是很 pythonic 或高效。我所做的是,我使用嵌套在 if 语句中的打印语句来获取类别标签 (i) 和打印到文件的金额。问题是我必须添加很多东西才能使整体正常工作。首先,我必须创建一个空列表以确保 if 语句不会在每次看到 'Description' 列中的所需项目时触发 .loc。其次,我不确定保存打印语句是否是最好的方法,因为它看起来很 ersatz。感觉离使用打卡又差了一步。简而言之,如果有人可以帮助我使我的代码更符合标准,我将不胜感激。
'''
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 中),但随后我在 'Amount' 列中得到了 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)
'''
您可以 select 只有符合条件的行
df[ a boolean matrix here ]
当执行 df["a column name"]=="value"
时,您实际上得到一个布尔矩阵,其中 "a column name"
== "value"
的行是 True
,其他行是 False
总结一下:Dataframe[Dataframe["Description"] == "banana"] 将为您提供一个新数据框的视图,其中只保留符合您条件的行。 (原始数据框未更改)
如果你 select 这个数据框的 "Amount"
列和 .sum()
它,你就得到了你想要的,在一行中。
这是典型的 pandadorable
(相当于 pythonic
for pandas)进行条件求和的方法。
如果需要,select 条件可以取多个值的数据框行,使用 .isin()
获取布尔矩阵
Dataframe["Description"].isin(["banana","apple"])
然后,在扫描数据框中“Description”的所有可能值时,在生成迭代器时使用 .unique()
。
然后您最终可以将系列附加到您的空数据框,然后再将其保存为 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() ] )