我收到这段代码将数据分组为直方图类型的数据。我一直试图理解这个pandas脚本中的代码,以便编辑、操作和复制它。我对我理解的部分有意见。在
import numpy as np
import pandas as pd
column_names = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6',
'col7', 'col8', 'col9', 'col10', 'col11'] #names to be used as column labels. If no names are specified then columns can be refereed to by number eg. df[0], df[1] etc.
df = pd.read_csv('data.csv', header=None, names=column_names) #header= None means there are no column headings in the csv file
df.ix[df.col11 == 'x', 'col11']=-0.08 #trick so that 'x' rows will be grouped into a category >-0.1 and <= -0.05. This will allow all of col11 to be treated as a numbers
bins = np.arange(-0.1, 1.0, 0.05) #bins to put col11 values in. >-0.1 and <=-0.05 will be our special 'x' rows, >-0.05 and <=0 will capture all the '0' values.
labels = np.array(['%s:%s' % (x, y) for x, y in zip(bins[:-1], bins[1:])]) #create labels for the bins
labels[0] = 'x' #change first bin label to 'x'
labels[1] = '0' #change second bin label to '0'
df['col11'] = df['col11'].astype(float) #convert col11 to numbers so we can do math on them
df['bin'] = pd.cut(df['col11'], bins=bins, labels=False) # make another column 'bins' and put in an integer representing what bin the number falls into.Later we'll map the integer to the bin label
df.set_index('bin', inplace=True, drop=False, append=False) #groupby is meant to run faster with an index
def count_ones(x):
"""aggregate function to count values that equal 1"""
return np.sum(x==1)
dfg = df[['bin','col7','col11']].groupby('bin').agg({'col11': [np.mean], 'col7': [count_ones, len]})
dfg.index = labels[dfg.index]
dfg.ix['x',('col11', 'mean')]='N/A'
print(dfg)
dfg.to_csv('new.csv')
我真正难以理解的部分是在这一部分:
^{pr2}$如果有人能评论这个剧本,我将不胜感激。也请随意更正或添加我的评论(这些是我目前为止认为可能不正确的)。我希望这对特种部队来说不是太离题。我很乐意给任何能帮助我的用户50分的奖励。在
我会尽力解释我的代码。因为它使用了一些技巧。在
df
,为pandas数据帧提供一个简写名称dfg
,意思是组mydf
。在让我建立一个表达式
dfg = df[['bin','col7','col11']].groupby('bin').agg({'col11': [np.mean], 'col7': [count_ones, len]})
dfg = df[['bin','col7','col11']]
表示从我的数据框df
中取名为“bin”“col7”和“col11”的列。在dfg = df[['bin','col7','col11']].groupby('bin')
完成的。我现在有了一组数据,即存储在bin#1中的所有记录,bin#2中的所有记录,等等dfg = df[['bin','col7','col11']].groupby('bin').agg({'col11': [np.mean]})
。记录的数量也很简单;python的len
函数(它不是真正的函数,而是列表等的属性)将给出list中的项数。所以我现在有了dfg = df[['bin','col7','col11']].groupby('bin').agg({'col11': [np.mean], 'col7': [len]})
。现在我想不出一个现有的函数来计算numpy数组中的个数(它必须在numpy数组上工作)。我可以定义自己在numpy数组上工作的函数,因此我的函数count_ones
。在现在我将解构
count_ones
函数。传递给函数的varibalex
始终是一个1d numpy数组。在我们的具体案例中,所有落在bin#1中的'col7'值,落在bin#2中的所有'col7'值,等等。。代码x==1
将创建一个与x大小相同的布尔(TRUE/FALSE)数组。如果x中的相应值等于1,则布尔数组中的条目将为TRUE,否则为FALSE。因为python将True视为1,如果我将布尔数组的值求和,我将得到一个==1的值的计数。现在我有了count_ones
函数,我通过:dfg = df[['bin','col7','col11']].groupby('bin').agg({'col11': [np.mean], 'col7': [count_ones, len]})
您可以看到
.agg
的语法是.agg({'column_name_to_apply_to': [list_of_function names_to_apply]}
使用布尔数组,您可以进行各种wierd条件组合(x==6)|(x==3)将是“x等于6或x等于3”。“and”运算符是&;。始终将
()
放在每个条件的周围现在到
dfg.index = labels[dfg.index]
。在dfg
中,因为我是按'bin'分组的,所以每一行分组数据的索引(或行标签)(即dfg.索引)会是我的垃圾箱数量:1,2,3,labels[dfg.index]
正在使用numpy数组的奇特索引。标签[0]会给我第一个标签,标签[3]会给我第四个标签。对于普通的python列表,您可以使用slices来做标签[0:3],这样可以得到标签0、1和2。使用numpy数组,我们可以更进一步,只使用一个值列表或另一个数组so标签来索引[np.数组([0,2,4])会给我标签0,2,4。通过使用labels[dfg.index]
我请求与bin对应的标签。基本上我把我的箱子编号换成箱子标签。我本可以对我的原始数据执行此操作,但这将是数千行;在分组之后执行此操作,我将对大约21行执行此操作。请注意,我不能只做dfg.index = labels
,因为我的一些箱子可能是空的,因此不在groupby data中。现在是
dfg.ix['x',('col11', 'mean')]='N/A'
部分。还记得很久以前我做df.ix[df.col11 == 'x', 'col11']=-0.08
的时候,我所有的无效数据都被当作一个数字来处理,并被放在第一个箱子里。应用groupby和aggregate函数后,我的第一个bin中“col11”值的平均值将为-0.08(因为所有这些值都是-0.08)。现在我知道这是不正确的,所有-0.08的值实际上都表示原始值wsa x。你不能求x的平均值。所以我手动将它设为N/a。即,dfg.ix['x',('col11', 'mean')]='N/A'
表示在dfg中,索引(或行)是'x',列是'col11 mean')将值设置为'N/A'。我相信('col11', 'mean')
是pandas如何产生聚合列名称的,即当我.agg({'col11': [np.mean]})
时,我需要('column_name', 'aggregate_function_name')
这一切的动机是:将所有数据转换成数字,这样我就可以使用Pandas的强大功能,然后在处理之后,手动更改我知道是垃圾的任何值。如果你需要更多的解释,请告诉我。在
相关问题 更多 >
编程相关推荐