我是新手。我在这个网站上寻找类似的问题,这帮助我想出了一个工作版本的代码,但我需要帮助,使它更专业。
我需要在pandas中迭代数据帧的行。我想做的是在"描述"列中找到相同的项目(例如杂货),并从"金额"列中找到它们的总(和)值,最后将结果写入.csv文件。我做这一切的原因是为我想基于这些类别创建的条形图编译数据。
在以下代码的帮助下,我能够完成所有这些,但这很可能不是很python化或高效。我所做的是使用嵌套在if语句中的print语句来获取类别标签(I)和要打印到文件的数量。问题是我必须添加很多东西才能使整体工作。首先,我必须创建一个空列表,以确保if语句在每次看到"Description"列中的所需项目时不会触发.loc。其次,我不确定保存print语句是否是最好的方法,因为它看起来非常虚假。感觉我离使用打孔卡还有一步之遥。总之,如果有人能帮助我使我的代码更符合标准,我将不胜感激。"
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)
"
只能选择符合条件的行df[ a boolean matrix here ]
当做df["a column name"]=="value"
时,你实际上得到一个布尔矩阵,其中"a column name"
=="value"
的行是True
,其他行是False
总结一下:Dataframe[Dataframe["Description"] == "banana"]将为您提供一个新数据框的视图,其中只保留符合您条件的行。(原始数据帧不改变)
如果您选择该数据框的"Amount"
列和.sum()
列,那么您在一行中就得到了所需的内容。这是典型的pandadorable
(相当于熊猫的pythonic
)进行条件和的方式。
如果需要,选择数据框中condition可以取多个值的行,使用.isin()
获取布尔矩阵
Dataframe["Description"].isin(["banana","apple"])
然后,扫描"description"中所有可能的值时在数据框架中,在生成迭代器时使用.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() ] )