目录
2.8.1 轴向旋转 pivot()、pivot_table()
2.1数据结构
2.1.1 Series
#创建方法
#1.用数组创建
data = np.array(['a', 'b', 'c', 'd', 'e'])
ds = pd.Series(data)
ds = pd.Series(data, index=np.arange(1,6))
#2.用字典创建
data = {
'a': 1.,
'b': 2.,
'c': 3.,
'd': 4.
}
ds = pd.Series(data)
ds = pd.Series(data, index=['d', 'c', 'b', 'a']) #不改变元素对应索引,但改变顺序
ds = pd.Series(data, index=['b', 'c', 'a', 'f']) #缺少元素用nan填充
#3.标量创建,必须提供index
ds = pd.Series(5, index=[0, 1, 2, 3])
#属性和常用方法
#1.用数组创建
data = np.array(['a', 'b', 'c', 'd', 'e'])
ds = pd.Series(data)
ds = pd.Series(data, index=np.arange(1,6))
#2.用字典创建
data = {
'a': 1.,
'b': 2.,
'c': 3.,
'd': 4.
}
ds = pd.Series(data)
ds = pd.Series(data, index=['d', 'c', 'b', 'a']) #不改变元素对应索引,但改变顺序
ds = pd.Series(data, index=['b', 'c', 'a', 'f']) #缺少元素用nan填充
#3.标量创建,必须提供index
ds = pd.Series(5, index=[0, 1, 2, 3])
2.1.2 DataFrame
#创建方法
#1.ndarray / 字典
data = {'one':[1,2,3,4],'two':[4,3,2,1]}
df = pd.DataFrame(data)
df = pd.DataFrame(data, columns=['two', 'one']) #指定列顺序
data = {'one':np.arange(1, 6, 1), 'two':np.arange(5, 0, -1)}
df = pd.DataFrame(data, columns=['two', 'one'], index=['a', 'b', 'c', 'd', 'e'])
#2.Series创建
data = {
'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']),
'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])
}
df = pd.DataFrame(data) #缺的补nan
#属性与方法
#1.属性
df.index
df.columns
df.axes
df.values, type(df.values)
df.ndim
df.size
df.shape
#2.方法
df.head(3)
df.tail(3)
df.info() #返回dataframe信息
df.describe()
2.2 常规数据读写
#读取
df = pd.read_csv('filename')
df.info()
pd.read_csv('URL/filename')
#分隔符 sep
#\s表示空白字符,包括但不限于空格、回车、换行、Tab,可用\s+
df = pd.read_csv('filename', delim_whitespace=True) #True时不设置delimiter
#表头
df = pd.read_csv('filename', sep=',', header=None) 默认第一行是表头
df = pd.read_csv('filename', sep=',', header=1) #纵向从0开始
#列名
df = pd.read_csv('filename', sep=',', names=range(38)) #0-37,此时保留原来表头,设置新表头
df = pd.read_csv('filename', sep=',', names=range(38), header=0)#覆盖表头=重新设置表头
#索引(行)
df = pd.read_csv('filename', index_col='hour')
df = pd.read_csv('filename', index_col=['date', 'hour', 'type'])
#使用部分列
df = pd.read_csv('filename', usecols=[0, 1, 2, 3])
df = pd.read_csv('filename', usecols=['东四', '天坛', '官园'])
#跳过指定行
df = pd.read_csv('filename', skiprows=[1,2,3,4])
df = pd.read_csv('filename', skiprows=[0]) #第0行被删掉,第一行变表头,第二行变第0行
df = pd.read_csv('filename', skiprows=[0],header=None)
df = pd.read_csv('filename', skiprows=8) #跳过前8行
df = pd.read_csv('filename', skiprows=lambda x: x % 2 != 0) #隔行跳过
#skip_blank_lines为True时跳过空行
#读取指定行
df = pd.read_csv('filename', nrows=10) #读取前10行
#通用解析函数
#表头前缀
df = pd.read_csv('filename', prefix='region_', header=None, skiprows=[0])
#列数据处理
df = pd.read_csv('filename', converters={'date': lambda x: pd.to_datetime(x)})
#把20200101变为2020-01-01 类型datetime64
df['date']
df['date'].dt.year, df['date'].dt.month, df['date'].dt.day #获取年月日
#空值替换
df = pd.read_csv('filename', na_values=20200101) #把日期变成nan了
#时间解析
df = pd.read_csv(
'filename',
parse_dates={'time': ['date', 'hour']},
converters={'hour': lambda x: x.zfill(2)}
)
df.head()
#txt文件读取
pd.read_table('filename.txt')
pd.read_csv('filename', sep='\t')
2.3 数据索引
2.3.1 中括号
#1.列索引
df['name1']
df[['name1', 'name2', 'name3']]
#2.行索引
df[0:1]
df[0::5] #0 ,5 ,10, ...
#4.联合索引
df[2::5][['name1', 'name2', 'name3']]
2.3.2 loc索引
#1.行索引
df.loc[0] #返回一列
df.loc[[0]] #返回一行
df.loc[[0, 5]]
df.loc[3::5]
#2.列索引
df.loc[:, 'name1']
df.loc[:, ['name1', 'name2', 'name3']]
#3.联合索引
df.loc[4::5, ['name1', 'name2', 'name3']]
2.3.3 iloc索引
#1.行索引
df.iloc[5]
df.iloc[[5]]
df.iloc[:5] #0-4
#2.列索引
df.iloc[:, 3]
df.iloc[:, 0:10:2]
#3.联合索引
df.iloc[::10, 1:20:3]
2.3.4 布尔索引
df[df['type']=='n']
df[(df['type']=='n') & (df['name1']<=50)]
df[(df['type']=='n') | (df['type']=='m')].head()
df.loc[df['type'].isin(['n', 'm'])].head()
df[~(df['type'].isin(['p', 'q']))]
2.4 数据清洗
None表示空值,类型是NoneType,不支持任何运算
Nan(Not a number)类型是float
要先把None变成Nan
2.4.1 缺失值剔除
df.isnull()
df.isnull().sum() #计算每列的缺失个数
df.isnull().sum(axis='columns') #计算每行的缺失个数
df.isnull().all() #每列是否全部缺失,返回列个布尔
#DataFrame.drop(index= ,columns= ,inplace=False)
df1 = df.drop(columns='name1')
df1 = df.drop('name1', axis=1) #axis=1和column意思一样
df1 = df.loc[:, ~(df.isnull().all())] #剩下的列没有全缺测的
df1[~(df1.isnull().any('columns'))] #剩下的每行一个缺测的都没有
df.dropna(axis='columns', how='all', inplace=True) #inplace是替换当前df
df.dropna(axis='index', how='any')
2.4.2 缺失值补全
df.fillna(method='ffill')
df.fillna(method='bfill')
df.drop(columns='type').fillna(0)
df.interpolate()
2.4.3 重复值处理
df2 = df.append(df.iloc[-2:])
df2.duplicated() #返回布尔,某行是否是重复的
df2.drop_duplicates() #返回删除结果
#某列重复剔除
df2.duplicated(subset=['name1'], keep=False) #true是有重复
df[df['name1'] == 41]
2.4.4 数据转换
#1.replace
df.replace(np.nan, -9999)
df.replace([np.nan, 0], -9999)
#2.apply()某行,n列;applymap()
k = df[df['type']=='k']
def k_level(k):
if k>0 and k<=50:
level = '优'
elif k>50 and k<=100:
level = '良'
elif k>100 and k<=150:
level = '轻度污染'
elif k>150 and k<=200:
level = '中度污染'
elif k>200 and k<=300:
level = '重度污染'
else:
level = '严重污染'
return level
k['name1'].apply(k_level)
k.loc[:, ~k.columns.isin(['date', 'hour', 'type'])].apply(np.mean, axis=0)
k.loc[:, ~k.columns.isin(['date', 'hour', 'type'])]
k.loc[:, ~k.columns.isin(['date', 'hour', 'type'])].applymap(k_level)
2.5 时间数据处理
2.5.1 时间数据格式
- 时间戳(timestamp)(datetimeindex):datetimes,to_datetime or date_range
- 时间周期(period)(periodindex):timespans, period or period_range
- 时间增量(timedelta)(timedeltaindex):timedeltas, to_timedelta or timedelta_range
2.5.2 时间戳
format 格式: datetime — Basic date and time types — Python 3.11.1 documentation
pd.Timestamp("2020/12/06") #Timestamp('2020-12-06 00:00:00')
pd.Timestamp(year=2020,month=12,day=6,hour=14,minute=19,second=52) #Timestamp('2020-12-06 14:19:52')
pd.Timestamp(df['date'][0]) #df['date'][0]是20200101,得到Timestamp('1970-01-01 00:00:00.020200101')
date = pd.to_datetime(df['date'][0]) #Timestamp('1970-01-01 00:00:00.020200101')
date = pd.to_datetime(df['date'][0], format='%Y%m%d') #Timestamp('2020-01-01 00:00:00')
#timestamp的属性
date.year
date.month
date.day
date.hour
date.minute
date.second
date.week
date.weekofyear
2.5.3 date_range 生成时间序列
pd.date_range('2020-01-01', '2020-02-08') #得到频率是每天
pd.date_range('2020-01-01', '2020-01-02', freq='H')
pd.date_range('2020-01-01', '2020-01-02', periods=24)
df.index = pd.date_range('2020-01-10', freq='D', periods=len(df.index))
#时间的索引
df = pd.read_csv(
'filename.csv',
parse_dates={'time': ['date', 'hour']},
converters={'hour': lambda x: x.zfill(2)}
)
df.index = df.time
df.drop(columns='time')
df['2020-01-01 20:00': '2020-01-01 22:00']
2.5.4 时间周期
#1.生成时间周期
pd.Period("2020/12/06")
time -3 #3天
pd.Period("2020/12/06", 'H')
time -3 #3小时
time = pd.Period(freq='S',year=2015, month=3,day=19, minute=43)
#2.period属性
time.freqstr
time.day
time.month
time.year
2.5.5 Period_range 时间序列
pd.period_range('2008/8/1', '2010/1/1', freq='M')
dates = pd.period_range(start='2010-01', freq='3M', periods=8)
dates + 1 #1是3个月
2.5.6 时间增量
pd.Timedelta(1, unit='D')
pd.Period("2020/12/06") + pd.Timedelta(1, unit='D') #加一天
pd.Period("2020/12/06") + pd.Timedelta(days=2) #加两天
pd.Timestamp("2020/12/06") + pd.Timedelta(hours=2) #加2小时
pd.DateOffset(year=2)
pd.Timestamp("2020/8/06") + pd.DateOffset(years=2, months=1, days=1)
2.6 数据的拼接与合并
- concat对series或dataframe进行行或列拼接
- merge将不同行连接起来
- join主要基于多个dataframe的索引进行合并
2.6.1 concat方法
默认行拼接,取并集
import pandas as pd
import glob
files = list(glob.glob('./地址/*'))
dfl = []
for f in files:
df = pd.read_csv(f)
dfl.append(df)
dfl[2]
pd.concat(dfl)
pd.concat(dfl, ignore_index=True)
pd.concat(dfl, keys=['1日', '2日', '3日'])
#行拼接
dfl = []
for f in files:
df = pd.read_csv(f)
dfl.append(df.T)
pd.concat(dfl, axis='columns')
#取交集
df1 = pd.read_csv(files[0])
df2 = pd.read_csv(files[1], usecols=[3,4,5,6])
pd.concat([df1, df2]), join='inner')
2.6.2 merge方法
df_left = pd.read_csv(files[0], usecols=range(8))
df_right=pd.read_csv(files[0],nrows=10,usecols=[0,1,2]+list(range(10,15))).append({'date':'8888'},ignore_index=True)
pd.merge(df_left,df_right) #默认取了交集
pd.merge(df_left,df_right,how='left') #left以左边的列为参考,右边没有的补nan
pd.merge(df_left, df_right, how='outer') #outer取并集
pd.merge(df_left,df_right,on=['hour','type','date'])#on是相同列合并
2.6.3 join方法
基于行索引上的合并
dataframe.join(other,on=None,how='',lsuffix='',rsuffix='',sort=False)
df=pd.read_csv(files[0],usecols=range(3,6),nrows=15)
others = pd.read_csv(files[0],usecols=range(10,13),nrows=8)
df.join(others)
others.join(df)
df.join(others,how='inner')
#若两个表格有重复列
df=pd.read_csv(files[0],usecols=range(6),nrows=15)
others = pd.read_csv(files[0],usecols=range[0,1,2]+list(range(10,15)),nrows=8)
df.join(others,lsuffix='_df',rsuffix='_others'
2.7 数据的分组与聚合
2.7.1 分组 groupby()
import pandas as pd
import glob
files=glob.glob('../data/C3.7/*')
df=pd.concat([pd.read_csv(f) for f in files])
df.dropna(axis='columns',how='all').dropna(axis='index',how='any')
df['date']=df.apply({'date':lambda x:pd.to_datetime(x,format='%Y%m%d')})
df['month']=df['date'].dt.month
#datafram.groupby(by= ,axis=0,level= ,
group = df.groupby('type') #简单分组
for i in group:
print(i)
df[df['type']=='AQI']
#2.多重分组
group = df.groupby(['type','month'])
for i in group:
print(i)
df[df['type']=='AQI' & df['month']==1]
2.7.2 聚合 agg()、transform()
#1.内置统计方法 2.agg 3.transform
#1. count,head,max,mean,median,cumcount,size,min,std,sum
aqi = df[df['type']=='AQI']
aqi.groupby('hour').max()
aqi.groupby(['hour','month']).mean()
#2.dataframe.agg(func,axis=0)
#对每列应用相同的函数
aqi.groupby(['month','hour']).agg([np.mean,np.std])
#对每列应用不同的函数
aqi.groupby(['month','hour']).agg({'东四':[np.mean,np.std],'天坛':[np.max,np.min]})
#3.transform
aqi.groupby('month').agg(np.mean)
aqi.groupby('month').tramsform(np.mean)
aqi.groupby('month').tramsform(lambda x:x-x.mean())#距平
2.8 数据重塑
2.8.1 轴向旋转 pivot()、pivot_table()
import pandas as pd
import glob
files = list(glob.glob('../../*'))
df = pd.concat([pd.read_csv(f) for f in files],ignore_index=True)
df.dropna(axis='columns',how='all').dropna(axis='index',how='any')
df.pivot(index=['date','hour'],columns='type',values='东四') #透视表
df.pivot(index=['date','hour'],columns='type')
df.pivot_table(index=['date','hour'],columns='type',values='东四',aggfunc=np.mean))
2.8.2 堆叠 stack()
#1.stack() 2.unstack()
data = df.pivot_table(index=['date','hour'],columns='type')
data.stack() #变窄变长
data.unstack() #变宽变短
2.9 图表数据可视化
import pandas as pd
import glob
files = list(glob.glob('./地址/*.csv'))
df = pd.concat([pd.read_csv(f) for f in files], ignore_index=True)
df = df.dropna(axis='columns', how='all').dropna(axis='index', how='any')
df['time'] = df['date'].astype('str') + df['hour'].astype('str').apply(lambda x: x.zfill(2))
df['time'] = df['time'].apply(lambda x: pd.to_datetime(x, format='%Y%m%d%H'))
data = df.drop(columns=['date', 'hour']).pivot_table(index='time', columns='type', values='东四')
aqi = data['AQI']
aqi.plot(backend='plotly')
data = df.drop(columns=['date', 'hour']).pivot_table(index='time', columns='type', values=['东四', '天坛', '官园'])
aqi = data.swaplevel(axis='columns')['AQI'] #swaplevel转变层级
aqi.plot(backend='plotly') #多条折线图
aqi.plot(y='天坛', backend='plotly')
aqi = data.groupby(data.index.month).mean().swaplevel(axis='columns')['AQI']
aqi.plot.bar(
backend='plotly',
barmode='group', #对变量分组
height=500, # 图表高度
width=800, # 图表宽度
)#得到柱状图
aqi.T.plot.bar(
backend='plotly',
height=500, # 图表高度
width=800, # 图表宽度
) #叠起来
看到了一篇写的很全的文章,也可参考