Python|pandas操作指南(超级详细!!!)

引言:最近pandas好久不用忘光光先写一点备着,以后实时更新防止自己忘掉,都是pandas最基本的概念,但是和别的博客有点不同,里面有着大量的实例可以帮助大家更好的理解pandas库的各个函数而不是枯燥的概念

pandas常用操作

  • 前期准备
  • 文件读取和保存
    • 普通保存
    • 类型切换保存
    • 保存时的设置参数
    • 大文件读取
    • 分类型读取
  • 数据处理
    • 数据前期预处理
    • 数据后期预处理(哑标,大小写,随机重排序)
    • 数据类型转换
    • 数据选取
    • 数据切割划分
    • 数据缺失
    • 数据填充
    • 数据去重
    • 数据替换
    • 数据分组
    • 数据聚合
    • 数据规整
      • 数据合并连接
      • 数据索引分层
      • 重命名轴索引
    • 数据排序
    • apply和map和lambda函数
    • 时间处理
      • 时间序列基础
      • 日期解析和提取
      • 时区转换
    • 正则表达式
    • 另外一些函数(sum,count,add,fill)
  • 典型筛选案例
    • 自定义函数
    • 函数组合
    • 其他(重采样,take,data-dict转换等)
  • numpy基础

前期准备 这里先提供一组数据集
data = https://www.it610.com/article/{'state':['Ohio2','Ohio2','Ohio2','Nevada2','Nevada2'], 'year':[2002,2012,2022,2012,2022], 'pop':[1.52,1.72,3.62,2.42,2.92], 'salary':['5000K/MTH - 20000K/MTH', '12K/MTH - 19K/MTH', '4000K/MTH - 6000K/MTH', '14000K/MTH - 22000K/MTH','8000K/MTH - 20000K/MTH'] } data = https://www.it610.com/article/pd.DataFrame(data)

文件读取和保存 普通保存
#读取 data = https://www.it610.com/article/pd.read_csv(r'E:\vscode_code\练习\文本练习\东方火锅.csv')#保存,这里保存为txt模式,所以参数要稍微变化 #显示以制表符分割,否则保存就是按照csv模式的逗号分割而不是txt的制表符分割 data.to_csv(r'E:\vscode_code\练习\文本练习\1.txt', sep = '\t', index = False) #普通的csv保存不需要制表符分割,因为他本身是以逗号进行分割 data.to_csv(r'E:\vscode_code\练习\文本练习\1.csv', index = False)

类型切换保存
#Excel文件 data = https://www.it610.com/article/pd.read_excel(r'E:\vscode_code\数据分析第二版\数据保存\文件测试\test.xlsx','Sheet1',index_col=0) #保存为csv data.to_csv(r'E:\vscode_code\数据分析第二版\数据保存\文件测试\test.csv',encoding='utf-8') #这个时候一定要加'header=None', 这样读进来的列名就是系统默认的0,1,2... 序列号,不然会把文件内容当做列名 data = https://www.it610.com/article/pd.read_csv(r'E:\vscode_code\数据分析第二版\数据保存\文件测试\test.csv', header=None)

保存时的设置参数
#第一: 一定要使用header = false, 不然的话保存数据集的时候,会自动使用0-n作为数据的列名。但如果是字典,就使用键值当索引 #第二: 一定也要使用index=False, 不然的话保存数据的时候,会自动加上一个索引列。 #第三: 如果不需要覆盖原文件, 用mode='a',默认是覆盖原文件的 #这里因为是字典带有键值,所以还是header=true,但是如果需要data.to_csv(r'E:\vscode_code\数据分析第二版\数据保存\1.csv', index=False, header=True) data2.to_csv(r'E:\vscode_code\数据分析第二版\数据保存\1.csv', index=False, mode='a', header=False) data3.to_csv(r'E:\vscode_code\数据分析第二版\数据保存\1.csv', index=False, mode='a', header=False)

大文件读取 在python中使用基本的pandas.read_csv打开文件时:MemoryError
import pandas as pd def knn(): #创建一个新的dataframe数据,用来append frame = pd.DataFrame() # 读取数据 file_path = r'E:\vscode_code\多线程\双色球\qiu2.csv'reader = pd.read_csv(file_path, chunksize=20)# 每块为20条数据(index)for chunk in reader: #这里需要重新设置索引,不然索引可能会重复 frame = frame.append(chunk).reset_index(drop=True) #print(chunk.head()) #只输出一块,把这个去掉就是所有数据了 #break print(frame.describe()) if __name__ == '__main__': knn()

分类型读取
df=pd.read_csv('text.csv', dtype={'code':str} ''' 这样,把你要转换的列的名字设定好, “code”列中的数据读取为str 这样,读取到的数据就是按照我们的要求的了。否则,类似001会读取成为1 '''

数据处理 数据前期预处理
#输出文件类型 print(data.info())#输出所包含的不重复内容 print(data['year'].unique())#数据的答题内容包含列名和数据个数 #但是这里经过测试,只有数字类型的才会被统计 print(data.describe())#默认前五个输出 print(data.head())#默认后五个输出 print(data.tail())#其他 data.index data.columns data.values#注意点 sdata = https://www.it610.com/article/{'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Utah': 5000} obj3 = pd.Series(sdata) #单个元素的字典直接转为DataFrame时,程序会报错,需要适当做些转换,指定行索引或者列索引才行 #sdata2 = {'Ohio': [35000], 'Texas': [71000], 'Oregon': [16000], 'Utah': [5000]} #obj4 = pd.DataFrame(sdata2) #print(obj3) #print(obj4) states = ['California', 'Ohio', 'Oregon', 'Texas'] obj4 = pd.Series(sdata, index=states)

数据后期预处理(哑标,大小写,随机重排序)
data = https://www.it610.com/article/pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami', 'corned beef', 'Bacon', 'pastrami', 'honey ham', 'nova lox'], 'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]}) #把他全部转化为小写字母 lowercased = data['food'].str.lower()#通过需要排列的轴的长度调用permutation,可产生一个表示新顺序的整数数组:(permuting,随机重排序) samper = np.random.permutation(5) print(samper) #take函数用以获取对应索引的信息 df.take(samper)#计算指标/哑变量######################################### #将分类变量(categorical variable)转换为“哑变量”或“指标矩阵”。 df = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'], 'data1': range(6)}) #print(df) #print(pd.get_dummies(df['key']))#给指标DataFrame的列加上一个前缀,以便能够跟其他数据进行合并 dummies = pd.get_dummies(df['key'], prefix='key') #print(dummies)

数据类型转换
data = https://www.it610.com/article/{'a':['1','2','3'],'b':['4','5','6']} data = https://www.it610.com/article/pd.DataFrame(data) #print(data)#这是修改两种数据类型的方法 pd.to_numeric(data['a'], errors='coerce') print(type(data.iloc[0,1])) #必须要经过赋值才能够实现 data['c'] = pd.to_numeric(data['a'], errors='coerce') print(data.iloc[2,2]) print(type(data.iloc[2,2])) data['b'] = data['b'].astype('int64') print(data.iloc[2,1]) print(type(data.iloc[2,1]))

数据选取
import pandas as pd import numpy as np ''' iloc主要使用数字来索引数据,而不能使用字符型的标签来索引数据。 而loc则刚好相反,只能使用字符型标签来索引数据,不能使用数字来索引数据, 不过有特殊情况,当数据框dataframe的行标签或者列标签为数字,loc就可以来其来索引。 ''' df=pd.DataFrame(np.arange(0,60,2).reshape(10,3),columns=list('abc')) print(df.loc[0,['a', 'b']])data = https://www.it610.com/article/{'state':['Ohio1','Ohio1','Ohio2','Nevada3','Nevada3'], 'year':[2000,2001,2002,2001,2002], 'pop':[1.5,1.7,3.6,2.4,2.9], 'salary':['1000K/MTH - 20000K/MTH', '7K/MTH - 8K/MTH', '10000K/MTH - 16000K/MTH', '3K/MTH - 5K/MTH', '7K/MTH - 12K/MTH',] } data = https://www.it610.com/article/pd.DataFrame(data) #报错原因:https://blog.csdn.net/niuniuyuh/article/details/76650904 #print(data.loc[0,1]) #print(data.loc[:,[0,3]]) #print(data.iloc[0:3,'state']) print(data.loc[0:3,'state']) print(data.iloc[0:3,0:3]) print(data.iloc[:,[0,3]]) #print(data.iloc([0,3]))这句是错的,因为参数没有指定完全data.index = ['a','b','c','d','e'] #报错原因:https://blog.csdn.net/niuniuyuh/article/details/76650904 #print(data.loc[0:3,'state']) print(data.loc['a']) print(data.loc[['a','b'], 'state'])#索引的其他用法################################3 #这两个索引函数也适用于一个标签或多个标签的切片: #print(data.loc[:'Utah', 'two']) #上下两种用法一样 #print(data.iloc[:, :3][data.three > 5]) #print(data.iloc[:, :3][data['three']>5])#pandas可以对不同索引的对象进行算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集。 s1 = pd.Series([7.3, -2.5, '', 1.5], index=['a', 'c', 'd', 'e']) s2 = pd.Series([-2.1, 3.6, -1.5, 4, 3.1],index=['a', 'c', 'e', 'f', 'g']) #print(s1 + s2)

数据切割划分
#离散化和面元划分############################# ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32] bins = [18, 25, 35, 60, 100] cats = pd.cut(ages,bins) #print(pd.value_counts(cats)) #你可以通过传递一个列表或数组到labels,设置自己的面元名称: group_names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior'] pd.cut(ages, bins, labels=group_names) #qcut是一个非常类似于cut的函数,它可以根据样本分位数对数据进行面元划分。

数据缺失
data.drop(data[data['标题'].isnull()].index, inplace = True)#若原处是空字符串还需要用np.nan替换,因为dropna只对np.nan处理 data.replace(to_replace=r'',value=https://www.it610.com/article/np.nan,regex=True,inplace=True) #注意下面两种的区别,第一个只对某一列处理,整体没变 data['标题'].dropna(axis = 0, inplace = True) #第二个才是对整体的处理 data.dropna(axis = 0,subset = ['标题'], inplace = True) #传入how='all'将只丢弃全为NA的那些行: data.dropna(how='all')

数据填充
#填充################################ data.fillna(0) #若是通过一个字典调用fillna,就可以实现对不同的列填充不同的值: data.fillna({1: 0.5, 2: 0}) #默认返回新对象,若对现有对象修改,用inplace参数 data.fillna(0, inplace=True) #里面还有别的参数可以了解

数据去重
#去重 #输出的只有state这一列 print(frame['state'].duplicated()) print(frame['state'].drop_duplicates())#输出的是经过去重后所有的数据 print(frame.drop_duplicates(['state'])) #保留最后一个 print(frame.drop_duplicates(['state'], keep='last'))

数据替换
#替换 #可以用字典对多个值进行替换 frame['year'].replace({2002:'1', 2012:'2'}, inplace=True) frame['state'].replace({'Ohio2':'1', 'Nevada2':'2'}, inplace=True)#替换################################# #map可用于修改对象的数据子集,而replace则提供了一种实现该功能的更简单、更灵活的方式 data = https://www.it610.com/article/pd.Series([1., -999., 2., -999., -1000., 3.]) #一次性替换多个值,可以传入一个由待替换值组成的列表以及一个替换值 data.replace([-999, -1000], np.nan) #要让每个值有不同的替换值,可以传递一个替换列表: data.replace([-999, -1000], [np.nan, 0]) #传入的参数也可以是字典: data.replace({-999: np.nan, -1000: 0})#针对csv的replace需要先转化成str print(data['标题链接'].str.replace('www', '').head())

数据分组
import pandas as pd import numpy as npdf = pd.DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'], 'key2' : ['one', 'two', 'one', 'two', 'one'], 'data1' : np.random.randn(5), 'data2' : np.random.randn(5)}) #group之后只是一个对象,可以对这个对象进行一系列操作 grouped = df['data1'].groupby(df['key1']) means = df['key2'].groupby(df['key1']) count = df['key1'].groupby(df['key2']) #print(means)states = np.array(['Ohio', 'California', 'California', 'Ohio', 'Ohio']) #print(df['data1'].groupby([states]).mean())#GroupBy的size方法,任何分组关键词中的缺失值,都会被从结果中除去。 #size跟count的区别: size计数时包含NaN值,而count不包含NaN值 #https://www.cnblogs.com/zknublx/p/12048410.html print(df.groupby(['key1', 'key2']).size())""" #GroupBy对象支持迭代,可以产生一组二元元组(由分组名和数据块组成) for name,group in grouped: print(name) print(group) """ #mapping传递 people = pd.DataFrame(np.random.randn(5, 5), columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis']) #你可以计算一个字符串长度的数组,更简单的方法是传入len函数: #print(people.groupby(len).sum())mapping = {'a': 'red', 'b': 'red', 'c': 'blue', 'd': 'blue', 'e': 'red', 'f' : 'orange'}by_column = people.groupby(mapping, axis=1) by_column.sum()#Series也有同样的功能,它可以被看做一个固定大小的映射: map_series = pd.Series(mapping)#还可以利用sample函数 #分类,当分类类别数超过总数,可用replace参数 choices = pd.Series([5, 7, -1, 6, 4]) #print(choices.sample(10,replace=True)) draws = choices.sample(n=10, replace=True)

数据聚合
import pandas as pd import numpy as nppeople = pd.DataFrame(np.random.randn(5, 5), columns=['a', 'b', 'c', 'd', 'e'], index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])def peak_to_peak(arr): return arr.max() - arr.min()#print(people.apply(peak_to_peak)) print(people.agg(peak_to_peak))

数据规整 数据合并连接
针对单独两列数据的合并,目前只想到用concat,merge一直报错
import pandas as pd """ #这两个:一、concat:沿着一条轴,将多个对象堆叠到一起;二、merge:通过键拼接列,是对于dataframe的合并pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=True, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None) pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, copy=True)#https://blog.csdn.net/brucewong0516/article/details/82707492 #https://blog.csdn.net/gdkyxy2013/article/details/80785361 """#str.cat是针对于拼接而非合并 data = https://www.it610.com/article/{'state':['Ohio1','Ohio1','Ohio2','Nevada3','Nevada3'], 'year':[2000,2001,2002,2001,2002], 'pop':[1.5,1.7,3.6,2.4,2.9], 'salary':['1000K/MTH - 20000K/MTH', '7K/MTH - 8K/MTH', '10000K/MTH - 16000K/MTH', '3K/MTH - 5K/MTH', '7K/MTH - 12K/MTH',] } data = https://www.it610.com/article/pd.DataFrame(data)data['a'] = data['state'].str.cat(data['salary'], sep = '-') #强制转化成了str之后就可以合并了 data['year_str'] = data['year'].astype('str') data['b'] = data['state'].str.cat(data['year_str'], sep = '-') print(data) #另一组测试数据集 left = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'], 'A': ['A0', 'A1', 'A2', 'A3'], 'B': ['B0', 'B1', 'B2', 'B3']}) right = pd.DataFrame({'key': ['K0', 'K1', 'K2', 'K3'], 'C': ['C0', 'C1', 'C2', 'C3'], 'D': ['D0', 'D1', 'D2', 'D3']}) result = pd.merge(left, right) print(result) #针对单独两列数据的合并,目前只想到用concat,merge一直报错 result = pd.concat([left['A'], right['C']], axis = 1)

数据索引分层
import numpy as np import pandas as pddata = https://www.it610.com/article/pd.Series(np.random.randn(9), index=[['a', 'a', 'a', 'b', 'b', 'c', 'c', 'd', 'd'], [1, 2, 3, 1, 3, 1, 2, 2, 3]]) #print(data) #通过unstack方法将这段数据重新安排到一个完整的DataFrame中: #print(data.unstack()) #unstack的逆运算是stack: data.unstack().stack()#可以实现分层索引 frame = pd.DataFrame(np.arange(12).reshape((4, 3)),index=[['a', 'a', 'b', 'b'], [1, 2, 1, 2]], columns=[['Ohio', 'Ohio', 'Colorado'], ['Green', 'Red', 'Green']]) #各层也可以有名字 frame.index.names = ['key1', 'key2'] frame.columns.names = ['state', 'color']#使用DataFrame的列进行索引######################################## frame = pd.DataFrame({'a': range(7), 'b': range(7, 0, -1), 'c': ['one', 'one', 'one', 'two', 'two', 'two', 'two'], 'd': [0, 1, 2, 0, 1, 2, 3]})#set_index函数会将其一个或多个列转换为行索引,并创建一个新的DataFrame: frame2 = frame.set_index(['c', 'd']) print(frame2) #默认情况下,那些列会从DataFrame中移除,但也可以将其保留下来: #frame.set_index(['c', 'd'], drop=False)#1.reset_index #reset_index可以还原索引,重新变为默认的整型索引 frame3 = frame2.reset_index(level = ['c']) print(frame3) #内置参数drop可以把原索引列给删除 frame = frame.append(frame).reset_index(drop=True) #2.reindex,其作用是创建一个新对象,它的数据符合新的索引 obj = pd.Series([4.5, 7.2, -5.3, 3.6], index=['d', 'b', 'a', 'c']) obj2 = obj.reindex(['a', 'b', 'c', 'd', 'e'])#sort_index:排序 obj=pd.Series([4,9,6,20,4],index=['d','a','e','b','c']) #按obj的索引排序,默认升序,降序可在括号加ascending=False print(obj.sort_index())

重命名轴索引
#重命名轴索引########################## data = https://www.it610.com/article/pd.DataFrame(np.arange(12).reshape((3, 4)), index=['Ohio', 'Colorado', 'New York'], columns=['one', 'two', 'three', 'four']) #1. transform = lambda x: x[:4].upper() data.index.map(transform) #data.rename()#内置参数

数据排序
#排序和排名 obj = pd.Series(range(4), index=['b', 'a', 'b', 'c']) obj.sort_index() #索引的is_unique属性可以告诉你它的值是否是唯一的: #print(obj.index.is_unique)

apply和map和lambda函数
import pandas as pd ''' apply 用在dataframe上,用于对row或者column进行计算;applymap 用于dataframe上,是元素级别的操作;map (其实是python自带的)用于series上,是元素级别的操作。 ''' df = pd.DataFrame(np.random.randint(0,10,(4, 3)), columns=list('bde'), index=range(4)) f = lambda x: x.max() - x.min() df.apply(f) df.apply(f,axis=1)# 作用在一行上 df.apply(f,axis=0)# 作用在一列上,axis=0可省略#applymap: 作用在dataframe的每一个元素上 f2 = lambda x: x+1 if x%2==0 else x df.applymap(f2) ############################################## #声明匿名函数 f = lambda x: x.max() - x.min() #这里的函数f,计算了一个Series的最大值和最小值的差 #在frame的每列都执行了一次。结果是一个Series,使用frame的列作为索引 frame.apply(f)#如果传递axis='columns'到apply,这个函数会在每行执行: frame.apply(f, axis='columns')#map函数############################ data = https://www.it610.com/article/pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami', 'corned beef', 'Bacon', 'pastrami', 'honey ham', 'nova lox'], 'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]}) meat_to_animal = { 'bacon': 'pig', 'pulled pork': 'pig', 'pastrami': 'cow', 'corned beef': 'cow', 'honey ham': 'pig', 'nova lox': 'salmon' } #Series的map方法可以接受一个函数或含有映射关系的字典型对象 #传入对象 data['animal'] = lowercased.map(meat_to_animal) #传入函数 data['food'].map(lambda x: meat_to_animal[x.lower()])

时间处理 时间序列基础
【Python|pandas操作指南(超级详细!!!)】ps:'data.a.dt.year’里面的dt是针对series类型的数据,其他的只需要a.year即可
import pandas as pd import numpy as np from datetime import datetime from datetime import timedelta from dateutil.parser import parse import pytz import time#字符串和datetime的互相转换 stamp = datetime(2011, 1, 3) #print(stamp) str(stamp)#处理缺失值,配合pandas idx = pd.to_datetime(datestrs + [None]) pd.isnull(idx)#时间序列基础############################################## #1.根据标签索引选取数据时,时间序列和其它的pandas.Series很像 dates = [datetime(2011, 1, 2), datetime(2011, 1, 5), datetime(2011, 1, 7), datetime(2011, 1, 8), datetime(2011, 1, 10), datetime(2011, 1, 12)]ts = pd.Series(np.random.randn(6), index=dates) #下面几种用法一样 ts[ts.index[4]] ts['1/10/2011'] ts['20110110'] ts['2011-1-2'] ts[datetime(2011,1,2)]#对于较长的时间序列,只需传入“年”或“年月”即可轻松选取数据的切片: #数字个数和日期个数必须对应 longer_ts = pd.Series(np.random.randn(10), index=pd.date_range('1/1/2000', periods=10)) #用法多样,只要索引符合规范 ts['2011-1-2':] ts[datetime(2011, 1, 7):] ts['1/6/2011':'1/11/2011']#2.面这些操作对DataFrame也有效 #生成的就是一个DatetimeIndex #pd.date_range(start='2012-04-01 12:56:31', periods=20, normalize=True) # 可以用start或end指定,normalize选项规范化(normalize)到午夜的时间戳 dates = pd.date_range('1/1/2000', periods=100, freq='W-WED') long_df = pd.DataFrame(np.random.randn(100, 4), index=dates, columns=['Colorado', 'Texas', 'New York', 'Ohio']) long_df.loc['5-2001']#产生重复 dates = pd.DatetimeIndex(['1/1/2000', '1/2/2000', '1/2/2000', '1/2/2000', '1/3/2000']) print(dates.dt.tz_convert('America/New_York'))dup_ts = pd.Series(np.arange(5), index=dates)#is_unique可以检查名字是否唯一 dup_ts.index.is_unique#传入level=0:可以把重复的索引分开 grouped = dup_ts.groupby(level = 0) grouped.mean() grouped.count()

日期解析和提取
import pandas as pd import numpy as np from datetime import datetime import time ###################解析日期########################## #datetime.strptime可以用这些格式化编码将字符串转换为日期: #datetime.strptime是通过已知格式进行日期解析的最佳方式,只能处理单个数据 value = 'https://www.it610.com/article/2011-01-03' value2 = datetime.strptime(value, '%Y-%m-%d') datestrs = ['7/6/2011', '8/6/2011'] #中括号得加 value3 = [datetime.strptime(x, '%m/%d/%Y') for x in datestrs] #print(value3)#dateutil可以解析几乎所有人类能够理解的日期表示形式: (parse('2011-01-03')) (parse('Jan 31, 1997 10:45 PM')) #在国际通用的格式中,日出现在月的前面很普遍,传入dayfirst=True parse('6/12/2011', dayfirst=True)#处理成组的日期 datestrs = ['2011-07-06 12:00:00', '2011-08-06 00:00:00'] pd.to_datetime(datestrs) #带有中文的日期格式 #1.单个操作,如要多组数据,用for语句 value = 'https://www.it610.com/article/2011年1月3号' value2 = datetime.strptime(value, '%Y年%m月%d号')#2.多组操作,适用于dataframe类型 datestrs = ['2011-07-06 12:00:00', '2011-08-06 00:00:00'] datestr = pd.to_datetime(datestrs) #针对有特定类型的日期类型 x = ['2011年7月6号', '2011年7月9号'] y = pd.to_datetime(x, format = '%Y年%m月%d号')#################转换和提取################# data = https://www.it610.com/article/{'state':['Ohio2','Ohio2','Ohio2','Nevada2','Nevada2'], 'year':['2002/1/2','2012/3/4','2022/5/6','2012/7/8','2022/9/10'], 'pop':[1.52,1.72,3.62,2.42,2.92], 'salary':['5000K/MTH - 20000K/MTH', '12K/MTH - 19K/MTH', '4000K/MTH - 6000K/MTH', '14000K/MTH - 22000K/MTH','8000K/MTH - 20000K/MTH'], 'create_time':[1462451334, 1462451335, 1461231336, 1462451337, 1462451338] } data = https://www.it610.com/article/pd.DataFrame(data) data['a'] = pd.to_datetime(data.year, format = '%Y-%m-%d') #print(data) #提取出年月日 #print(data.a.dt.year, data.a.dt.month, data.a.dt.day)#python中type,dtype,astype的作用与使用要注意,第一个针对单个,第二个针对数组等多个元素 print(type(data.a.dt.year)) print(data.a.dt.year.dtype)#时间戳转换 timestamp = 1462451334#转换成localtime time_local = time.localtime(timestamp) #转换成新的时间格式(2016-05-05 20:28:54) dt = time.strftime("%Y-%m-%d %H:%M:%S",time_local) print (dt)#pandas里面时间戳转换 data['date']= pd.to_datetime(data['create_time'].values, utc=True, unit='s').tz_convert( "Asia/Shanghai").to_period("D") print(data)

时区转换
#时区划分 #时区名字 #时区是以UTC偏移量的形式表示的 pytz.common_timezones[1:15] #获取时区对象 tz = pytz.timezone('America/New_York')#freq就表示时间频率,D代表day,W就代表week,tz就代表时区 rng = pd.date_range('3/9/2012 9:30', periods=6, freq='D') #rng2已经规定了时区,相当于已经本地化过了 rng2 = pd.date_range('3/9/2012 9:30', periods=6, freq='D', tz='UTC')#print(rng.tz_localize('Asia/Shanghai')) #从单纯到本地化的转换是通过tz_localize方法处理的: ts_utc = rng.tz_localize('UTC') #print(ts_utc) #一旦时间序列被本地化到某个特定时区,就可以用tz_convert将其转换到别的时区了: #print(ts_utc.tz_convert('America/New_York'))#tz_localize和tz_convert也是DatetimeIndex的实例方法: ts = pd.Series(np.random.randn(len(rng)), index=rng) #print(ts.index) #print(ts.index.tz_localize('Asia/Shanghai'))#srtftime的使用

正则表达式
#pandas里面的正则############################################### #1.extract使用 #如果提取的规则结果有多组,则会返回数据框,不匹配的返回NaN s3 = pd.Series(['a1', 'b2', 'c3']) print(s3.str.extract('([ab])(\d)')) #print(pd.Series(s3).str.extract('([ab])(\d)', expand=False)) print(pd.Series(['a1', 'b2', 'c3']).str.extract('([ab])(\d)', expand=False))#2.contains使用正则表达式, #可以将符合的数据进行提取 #print(s3.str.contains('([ab])(\d)')) #print(s3[s3.str.contains('([ab])(\d)')].unique())data = https://www.it610.com/article/{'state':['Ohio1','Ohio1','Ohio2','Nevada3','Nevada3'], 'year':[2000,2001,2002,2001,2002], 'pop':['1.5','1.7','3.6','2.4','2.9'], 'salary':['1000K/MTH - 20000K/MTH', '7K/MTH - 8K/MTH', '10000K/MTH - 16000K/MTH', '3K/MTH - 5K/MTH', '7K/MTH - 12K/MTH',] } frame = pd.DataFrame(data)#series是将数据形成一个个的列表 #正则记得加括号 #print(pd.Series(data['pop']).str.extract('(\d+\.?\d)'))#series和dataframe##################################################################### #注意:extract在dataframe中也适用,不需要再次series,其实series相当于dataframe的一列而已 #所以,诸如head,unique,describe对于dataframe可用的对于series也可用 #print(frame['pop'].str.extract('(\d+\.?\d)')) #这两个结果就是一样的 #print(pd.Series(data['pop']),'\n', frame['pop'])#打换行符的时候,需要用引号弄起来哦 data2 = ['1.5','1.7','3.6','2.4','2.9'] #纯数字列表无法用.str方法 #data2 = [1.5,1.7,3.6,2.4,2.9]#print(data2, '\n' , pd.Series(data2)) data3 = pd.Series(data2) #print(data3.str.extract('(\d+\.?\d)'))#re在字符串和pandas中的应用###################################################### #若是字典,那么键值将充当索引 data = https://www.it610.com/article/{'Dave': 'dave@google.com', 'Steve': 'steve@gmail.com', 'Rob': 'rob@gmail.com', 'Wes': np.nan}data = https://www.it610.com/article/pd.Series(data) #提取,但是.str只针对dataframe或series形式 #print(data.str[:5])data.isnull() data.str.contains('gmail') pattern = '([A-Z0-9._%+-]+)@([A-Z0-9.-]+)\\.([a-z]{2,4})'#这里用加号和括号就可以把正则提取的东西分别存储在列表中 #print(data.str.extract('([a-z0-9._%+-]+)(@+)([a-z0-9.-]+)\\.([a-z]{2,4})'))#使用正则表达式,还可以加上任意re选项(如IGNORECASE),这个貌似不看大小写吧好像 #print(data.str.findall(pattern, flags=re.IGNORECASE))#获取true或false matches = data.str.match(pattern, flags=re.IGNORECASE)#例子######################################################## def Find(string): # findall() 查找匹配正则表达式的字符串 url = re.findall('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', string) #'https://([\w.])+'也是对的 return url string = 'Runoob 的网页地址为:https://www.runoob.com,Google 的网页地址为:https://www.google.com' print("Urls: ", Find(string)) '''

另外一些函数(sum,count,add,fill)
import pandas as pddata = https://www.it610.com/article/{'state':['Ohio2','Ohio2','Ohio2','Nevada2','Nevada2'], 'year':[2002,2012,2022,2012,2022], 'pop':[1.52,1.72,3.62,2.42,2.92], 'salary':['5000K/MTH - 20000K/MTH', '12K/MTH - 19K/MTH', '4000K/MTH - 6000K/MTH', '14000K/MTH - 22000K/MTH','8000K/MTH - 20000K/MTH'] } frame = pd.DataFrame(data) #这个只针对非str的数据相加求总和 print(frame.groupby(data['state']).sum()) #这个则是分组计算数目 print(frame.groupby(data['state']).count())#使用df1的add方法,传入df2以及一个fill_value参数,就是一个填充值,不然会用NaN代替,他的数学运算是按照索引一一对应! #print(s1.add(s2,fill_value = https://www.it610.com/article/0)) #实例 #当计算结果为NAN时,需要用特定的值来补充代替 import pandas as pd s1=pd.Series([1,2,3,4],index=['a','b','c','d']) s2=pd.Series([10,20,30,40],index=['c','d','e','f']) s3=pd.Series([1,2,3,4],index=['a','b','c','d']) s4=pd.Series([10,20,30,40],index=['c','d','e','f']) print (s1+s2) #--1--直接相加只有索引c\d对应有值 print ((s1+s2).dropna())#--2--去除值为空的 print ((s1+s2).fillna(0))#--3--把值为空的地方填充成0 print (s1.add(s2,fill_value=https://www.it610.com/article/1)) #--4--s1和s2相加,当索引对应值不存在,用1代替s2中元素和s1相加#针对索引 #pandas可以对不同索引的对象进行算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集。 s1 = pd.Series([7.3, -2.5,'', 1.5], index=['a', 'c', 'd', 'e']) s2 = pd.Series([-2.1, 3.6, -1.5, 4],index=['a', 'c', 'e', 'f']) print(s1 + s2)

典型筛选案例 自定义函数
import pandas as pd import numpy as np import re#针对于字符串的替换筛选########################################### salary = ['8千-1万', '5千-8千', '面议', '1.5万-2万', '1.5万-3万', '1万-1.5万', '7千-1.5万', '1.5万-2.5万', '1万-2万', '8千-1.5万', '2.5万以上', '7千-1万', '3千-8千', '2千-1万', '5千-1万', '4千-1万', '5千-6千', '3千-5千', '2万-2.5万', '6千-1万'] salary = pd.Series(salary)def process_k(data): if '千' in data: return float(data.replace('千', '')) * 1000 elif '万' in data: return float(data.replace('万', '')) * 10000def process_salary(data): if data =https://www.it610.com/article/='面议': return np.nan if '万以上' in data: return float(data.replace('万以上', '')) * 10000 if '千以下' in data: return float(data.replace('千以下', '')) * 1000 if '-' in data: low, high = data.split('-') return (process_k(low) + process_k(high))/2salary_clean = salary.apply(process_salary) #salary_clean = salary_clean[salary_clean>10000] print(salary_clean) #print(salary_clean.unique())#针对于数字和字符串的清洗筛选############################################ data = https://www.it610.com/article/{'state':['Ohio1','Ohio1','Ohio2','Nevada3','Nevada3'], 'year':[2000,2001,2002,2001,2002], 'pop':[1.5,1.7,3.6,2.4,2.9], 'salary':['1000K/MTH - 20000K/MTH', '7K/MTH - 8K/MTH', '10000K/MTH - 16000K/MTH', '3K/MTH - 5K/MTH', '7K/MTH - 12K/MTH'] } frame = pd.DataFrame(data)def get_salary_jlc(data): pat_jlc = r"(.*)K/MTH - (.*)K/MTH" if '00' in data: low, high = re.findall(pattern=pat_jlc, string=data)[0] return (float(low)+float(high))/2/1000 else: low, high = re.findall(pattern=pat_jlc, string=data)[0] return (float(low)+float(high))/2frame['salary_clean'] = frame['salary'].apply(get_salary_jlc)#print(frame.head()) #print(frame['salary'].iloc[:3]) x = re.findall("(.*)K/MTH - (.*)K/MTH", '1000K/MTH - 20000K/MTH') #print(x) low, high = re.findall("(.*)K/MTH - (.*)K/MTH", '1000K/MTH - 20000K/MTH')[0] #print(low,' ', high)

函数组合
#所有元素的累计和 print(data['a'].astype('int64').sum()) print(data['a'].cumsum()) print(data['a'].astype('int64').sort_values(ascending = False)) ''' #非空元素的数量 print(data['b'].notnull().sum()) #第a列索引为2的元素 print(data.a[2])#检测和过滤异常值,一般就依靠算法了##################### #生成4组,每一组包含1000个元素,numpy.random.rand()则相反 data = https://www.it610.com/article/pd.DataFrame(np.random.randn(1000, 4)) #print(data[2][np.abs(data[2])>3]) #print(data[(np.abs(data) > 3).any(1)])#字符串对象方法########################### val = 'a,b,guido' val1 = val.split(',') #strip方法不支持列表操作 pieces = [x.strip() for x in val.split(',')] print(val1,' ',pieces) #可以直接赋值 first, second, third = pieces #下面两种方法一样 first + '::' + second + '::' + third '::'.join(pieces)

其他(重采样,take,data-dict转换等)
import numpy as np; import pandas as pdvalues = pd.Series([0, 1, 0, 2] * 2) dim = pd.Series(['apple', 'orange','banana'])#可以使用take方法存储原始的字符串Series: #用于分类,但是values和dim里面的类别数量必须相等,否则报错 #print(dim.take(values))# fruits = ['apple', 'orange', 'apple', 'apple'] * 2N = len(fruits) df = pd.DataFrame({'fruit': fruits, 'basket_id': np.arange(N), 'count': np.random.randint(3, 15, size=N), 'weight': np.random.uniform(0, 4, size=N)}, columns=['basket_id', 'fruit', 'count', 'weight'])#dtypes(查询数据类型) 、astype(强制转换数据类型) fruit_cat = df['fruit'].astype('category') #print(fruit_cat)#GroupBy高级应用################################# df = pd.DataFrame({'key': ['a', 'b', 'c'] * 4, 'value': np.arange(12.)})g = df.groupby(df['key']) print(g.mean())#重采样 df = pd.DataFrame({'time': np.arange(N * 3.), 'key': np.tile(['a', 'b', 'c'], N), 'value': np.arange(N * 3.)}) print(df) print(df.set_index('key'))#下面用法自行体会 data = https://www.it610.com/article/{'col_1': [3, 2, 1, 0], 'col_2': ['a', 'b', 'c', 'd']} data1 = pd.DataFrame.from_dict(data) data2 = pd.DataFrame(data) data3 = pd.DataFrame.from_dict(data, orient='index', columns=['A', 'B', 'C', 'D']) print(data1) print(data2) print(data3)

numpy基础
import numpy as npmy_arr = np.arange(10) #print((my_arr)[1]) my_list = list(range(10)) #print(my_list[1])arr = np.arange(8) #1.数组重塑################################################### arr2 = arr.reshape(4,2) #reshape将一维数组转换为多维数组的运算过程相反的运算通常称为扁平化(flattening)或散开(raveling): arr3 = arr2.ravel() arr4 = arr2.flatten() #print(arr3, arr4)#2.数据的合并和拆分#############################################3 arr1 = np.array([[1, 2, 3], [4, 5, 6]]) arr2 = np.array([[7, 8, 9], [10, 11, 12]]) #按列合并 np.concatenate([arr1, arr2], axis=0) #按行合并 np.concatenate([arr1, arr2], axis=1)#对于常见的连接操作,NumPy提供了一些比较方便的方法(如vstack和hstack) #按列合并 np.vstack((arr1, arr2)) #按行合并 np.hstack((arr1, arr2))#与此相反,split用于将一个数组沿指定轴拆分为多个数组:传入到np.split的值[1,3]指示在哪个索引处分割数组。 arr = np.random.randn(5, 2) first, second, third = np.split(arr, [1,3])#3.元素的重复操作:tile和repeat###################################### arr = np.arange(3) arr.repeat(3) #如果传入的是一组整数,则各元素就可以重复不同的次数:但是个数也必须对应 #同样,在对多维进行重复时,也可以传入一组整数,这样就会使各切片重复不同的次数: arr.repeat([2, 3, 4]) #对于多维数组,还可以让它们的元素沿指定轴重复: arr = np.random.randn(2, 2) arr.repeat(2, axis = 1) #注意,如果没有设置轴向,则数组会被扁平化,这可能不会是你想要的结果 #print(arr.repeat(2))#4.索引:################################################ # 获取和设置数组子集的一个办法是通过整数数组使用花式索引: arr = np.arange(10) * 100 inds = [7, 1, 2, 6] #两种方法一样 arr[inds] arr.take(inds) #在inds索引处的数用42代替 arr.put(inds, 42)#要在其它轴上使用take,只需传入axis关键字即可: arr = np.random.randn(2, 4) print(arr) #抽取arr按行的每个数据的第1,2个 print(arr.take([0, 1], axis =1))

我写不动了,下次再补。。。

    推荐阅读