最近参加比赛,需要处理各种各样的数据。不得不说,pandas给我带来了很大的方便。困于一直没整理,每一次用到都要查官方文档。现在打算慢慢把用到的函数记录下来,积少成多。
(1)df.value_counts():统计具体某一列相同值的个数
for example:有下面一个表,这个表有300万行,这里只截取一部分举例。我想统计item_id这一列中每一个相同id的个数
代码如下:
import pandas as pd
df = pd.read_csv('./train.csv')
df['item_id'].value_counts()
Out[3]: ###以下是部分统计结果,左边是具体的item_id,右边是该item_id的个数
543083 9899
549608 9034
542524 8511
540198 8112
550192 7984
543092 7459
542973 7370
542907 7135
如果我想把出现个数最高的前3个item_id统计出来,并保存为数组,该怎么做呢?
代码如下:
import numpy as np
np.array(df['item_id'].value_counts()[:3].keys())
Out[6]: array([543083, 549608, 542524], dtype=int64) ###可以看到,结果为上述统计中个数最大的前三个,符合我们的要求
(2) 取dataframe的某几列:df.ix
import pandas as pd
df = pd.read_csv('./data.csv',nrows=5) #nrows表示取整个数据集的前5行
dt = df.ix[:,5:15] ##这里取df的所有行,第5到14列
(3)将数据集的部分列相加,并添加到最后一列中:
import pandas as pd
import numpy as np
df = pd.read_csv('./data.csv',nrows=5) #nrows表示取整个数据集的前5行
dt = df.iloc[:,:].values
ds = np.sum(dt[:,313:],axis=1) #对313列到最后列的所有列求和
ds = pd.DataFrame(ds)ds.columns = ['用户浏览各网站之和'] ##添加列名
df = pd.concat([df,ds],axis=1) #将新列ds添加到原来的数据集df中
(4)查找含有缺失值的列:df.isnull().any()
import pandas as pd
df = pd.read_csv(filename)
dt = df.isnull().any()
dic = {}
for i in range(len(dt)):
dic[dt.index[i]] = dt[i]
all_nan = []
for key,item in dic.items():
if item == True:
all_nan.append(key)
print (all_nan)
(5)缺失值补全:df.fillna。(注意,fillna默认会返回新对象)
import pandas as pd
df = pd.read_csv(filename)
df = df.fillna(0) ##对所有缺失值用零补全
df = df.fillna(df.mean()) ##对每一列用平均值补全
df = df.fillna({'列名':'要补全的值',...}) ##用字典可以对不同的列填充不同的值
(6)如何统计两列元素都相同的样本个数?
举个栗子:我要统计100万个用户使用的手机品牌和手机型号都相同的个数
import pandas as pd
import numpy as np
df = pd.read_csv(filename)
#1.先创建一个全为1的列
new_col = pd.DataFrame(np.ones(len(df)))
new_col.columns = ['one']
df = pd.concat([df,new_col],axis=1)
#2.统计个数
dt = df.groupby(['手机品牌','手机型号']).one.sum()
#3.排序
d = dt.sort_values()
部分结果如下图:
PS:这只是我想到的一个方法,读者如果有更方便的方法,烦请不吝赐教。
(7)对列的每个元素进行处理:map()函数
def crate(x,all_label):
if x == 0:
return all_label[0]
elif x > 0 and x <= 10:
return all_label[1]
elif x > 10 and x <= 20:
return all_label[2]
elif x > 20 and x <= 30:
return all_label[3]
elif x > 30 and x <= 50:
return all_label[4]
elif x > 50:
return all_label[5]
all_label = [1,2,3,4,5,6] ##all_label可以是一个随for循环而变化的数组,这里为了简单起见,用一个简单数组代替
df['新列名'] = df['列名'].map(lambda x:crate(x,all_label)) ##关键是这一句,lambda后面跟的x是自变量,相当于列中的元素,冒号后面是对每个元素的函数操作。
(8)删除不同的列:
df = df.drop(['a','b'],axis=1) #'a','b'为相应的列名
删除连续多列:
df.drop(df.columns[8:308], axis=1,inplace=True)
(9)双重条件下的平均值
举个栗子:我现在有三列:用户年龄段(离散为0-8),用户大致消费水平(离散为0-8),用户的刷卡次数(连续值),我要统计不同年龄段不同消费水平下的平均刷卡次数,并成为新的一列加到原数据中,怎么做呢?
其实原理和求不同年龄段的平均刷卡次数的原理相同,只是在此基础上添加一列。
import pandas as pd
dt = pd.read_csv(filename)
dd = pd.DataFrame(dt.groupby(['年龄段','大致消费水平']).每月的大致刷卡消费次数.mean()).reset_index()
dd.columns = ['年龄段','大致消费水平', '平均刷卡次数']
dt = dt.merge(dd, on=['年龄段','大致消费水平'], how="left")
把每一行中的'大致消费水平'这一项去掉,就是求不同年龄段的平均刷卡次数的方法。
其他求中位数,求和等只要把.mean()换成.median(),.sum()等相应的函数即可。
(10)对所有行或者列求和:
df.drop_duplicates(subset=['name'], keep='first', inplace=True)
其中subset表示要判断的列,keep='first'表示对相同的行只保留第一行,inplace=True表示修改后的值直接赋给df.
(13) isin()取出某列的元素在某个list范围内的所有行:
df = df[df['subject_1'].isin([1, 2, 3, 4, 5])]
df=df.dropna(subset=['列名'])
(15)使用apply同时处理两列数据的方法:
def my_test(a, b):
return a + b
df['Value'] = df.apply(lambda row: my_test(row['a'], row['c']), axis=1)
(16) dict转dataframe,将keys作为数据列,并重新命名
student_comments = pd.DataFrame.from_dict(redis_data, orient='index', columns=['comment_count_type']).reset_index().rename(columns={'index': 'student_id'})
(17) 对列a根据两列进行groupby, 并且列a的元素进行聚合,并重设索引
perform_agg = perform['detail'].groupby(
[perform['in_class'], perform['performance_type']]).aggregate(lambda x: ','.join(x)).reset_index()
(18) 将pandas的两列转换为字典,其中一列的元素为Key,另一列的元素为value.
detail = dict(zip(perform.iloc[:, 0], perform.iloc[:, 1])) # 0,1为列对应的位置
dict转dataframe,将keys作为数据列,并重新命名