我收到此代码可将数据分组为直方图类型数据。我一直试图理解这个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')
我真正难以理解的部分在本节中:
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')
如果有人能够评论这个剧本,我将非常感激。也可以随意纠正或添加我的评论(这些是我假设到目前为止他们可能不正确)。我希望这不是SOF的主题。我很乐意为任何可以帮助我的用户提供50点奖励。
答案 0 :(得分:8)
我会尝试解释我的代码。因为它使用了一些技巧。
df
,为pandas DataFrame提供简写名称dfg
,即将我的df
分组。让我建立表达式dfg = df[['bin','col7','col11']].groupby('bin').agg({'col11': [np.mean], 'col7': [count_ones, len]})
dfg = df[['bin','col7','col11']]
正在说出名为&#39; bin&#39;的列。 &#39; COL7&#39;和&#39; col11&#39;来自我的DataFrame df
。dfg = df[['bin','col7','col11']].groupby('bin')
完成的。我现在有数据组,即bin#1中的所有记录,bin#2中的所有记录等等。dfg = df[['bin','col7','col11']].groupby('bin').agg({'col11': [np.mean]})
。记录数量也很容易; python的len
函数(它不是真正的函数,而是列表的属性等)将为我们提供列表中的项目数。所以我现在有dfg = df[['bin','col7','col11']].groupby('bin').agg({'col11': [np.mean], 'col7': [len]})
。现在我不能想到一个现有的函数来计算一个numpy数组中的一个(它必须在一个numpy数组上工作)。我可以定义自己的函数来处理numpy数组,因此我的函数count_ones
。 现在我将解构count_ones
函数。传递给函数的varibale x
总是一个1d numpy数组。在我们的具体情况下,它将是所有&#39; col7&#39; bin#1中的值,所有&#39; col7&#39;落在bin#2等中的值。代码x==1
将创建一个与x相同大小的布尔(TRUE / FALSE)数组。如果x中的相应值等于1,则布尔数组中的条目将为True,否则为false。因为如果我将我的布尔数组的值相加,python将True视为1,我将得到== 1的值的计数。现在我已经拥有了count_ones
功能,我将其应用于&#39; col7&#39;作者: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]}
使用布尔数组,您可以执行各种奇怪的条件组合(x == 6)| (x == 3)将是&x; x等于6或x等于3&#39;。 &#39;和&#39;运营商是&amp ;.始终将()
置于每个条件
现在到dfg.index = labels[dfg.index]
。在dfg
中,由于我按照&#39; bin&#39;分组,每行分组数据(即我的dfg.index)的索引(或行标签)将是我的bin编号:1,2, 3,labels[dfg.index]
正在使用numpy数组的花式索引。标签[0]会给我第一个标签,标签[3]会给我第4个标签。使用普通的python列表,你可以使用切片来做标签[0:3],它会给我标签0,1和2.对于numpy数组,我们可以更进一步,只需使用值列表或另一个数组进行索引,这样就可以了[np.array([0,2,4])会给我标签0,2,4。通过使用labels[dfg.index]
我请求对应于bin#的标签。基本上我将我的bin编号改为bin标签。我本可以对原始数据做到这一点,但这将是数千行;通过我在小组之后做到21行左右。请注意,我不能只执行dfg.index = labels
,因为我的某些垃圾箱可能是空的,因此数据不会出现在组中。
现在是dfg.ix['x',('col11', 'mean')]='N/A'
部分。请记住当我执行df.ix[df.col11 == 'x', 'col11']=-0.08
时,我的所有无效数据都被视为一个数字并将被放入第一个bin中。在应用分组和汇总功能后,&#39; col11&#39;的平均值我的第一个bin中的值将是-0.08(因为所有这些值都是-0.08)。现在我知道这不正确,-0.08的所有值实际上表示原始值为wsa x。你不能做x的意思。所以我手动把它放到N / A.即。 dfg.ix['x',('col11', 'mean')]='N/A'
表示在dfg中,索引(或行)是&#39; x&#39;和列是&#39; col11表示&#39;)将值设置为&#39; N / A&#39;。 ('col11', 'mean')
我相信大熊猫是如何提出聚合列名称的,即当我.agg({'col11': [np.mean]})
时,引用我需要('column_name', 'aggregate_function_name')
所有这一切的动机是:将所有数据转换为数字,以便我可以使用Pandas的强大功能,然后在处理之后,手动更改我知道的任何垃圾值。如果您需要更多解释,请与我们联系。