前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pandas多表操作,groupby,时间操作

pandas多表操作,groupby,时间操作

作者头像
李智
发布2018-08-03 17:28:52
3.7K0
发布2018-08-03 17:28:52
举报
多表操作
  • merge合并 pandas.merge可根据一个或多个键将不同DataFrame中的行合并起来
pd.merge(left, right)# 默认merge会将重叠列的列名当做键,即how='inner',有多个重复列名则选取重复列名值都相同的行

# 指定“on”作为连接键,left和right两个DataFrame必须同时存在“on”列,连接键也可N对N(少用)
pd.merge(left, right, on="key")#默认how='inner',两个表取key的交集行,right的的列放在left列右边
pd.merge(left, right, on=["key1", "key2"])#两个表取key1,key2都相同的行,right的的列放在left列右边

pd.merge(left,  right,  left_on="key",  right_on="key")#两个表取key列行相同的行,其他重复列名变为column_x,column_y,与on='key'相同

# suffixes:用于追加到重叠列名的末尾,默认为("_x", "_y")
pd.merge(left,  right,  on="key",  suffixes=("_left",  "_right"))

# 指定连接方式:“inner”(默认),“left”,“right”,“outer”
pd.merge(left, right,on='key' how="outer")#产生以left和right的key值并集的行的dataframe

pd.merge(left_frame, right_frame, on='key', how='left')#产生以left_frame的key所有值为行的dataframe,right_frame中的key没有该值的话那些列数据为NaN

pd.merge(left_frame, right_frame, on='key', how='right')#同上相似

pd.merge(left,  right,  left_on="lkey",  right_on="rkey")#左边表lkey和右边表rkey值相同的行,所有列都显示,重复的_x,_y
  • 索引上的合并(可用join代替,而且join更方便)
# 索引和索引连接
pd.merge(left,  right,  left_index=True,  right_index=True)
# "key"和索引连接
pd.merge(left,  right,  left_on="key",  right_index=True)
# 层次化索引
pd.merge(left,  right,  left_on=["key1", "key2"],  right_index=True)
  • join连接
# 用left的索引和right的索引进行merge
left.join(right)

# 用left的索引和right的“key”进行merge
left.join(right, on="key")

# 层次化索引
left.join(right, on=["key1", "key"])

# join可以合并两张以上的表,而merge只能合并两张表
left.join([right1, right2], how="outer")
  • concat 轴向连接 pandas.concat可以沿着一条轴将多个表对象堆叠到一起:因为模式how模式是“outer”
# 默认 axis=0 上下拼接,列column重复的会自动合并
pd.concat([df1, df2], axis=0)

# axis=1 左右拼接,行raw/index重复的会自动合并
pd.concat([df1, df2], axis=1)

# 忽略df1和df2原来的index,重新给新的DataFrame设置从0开始的index
pd.concat([df1,df2],  ignore_index=True)
  • append 使用场景:表头一致的多张表,进行连接(上下连接)
df1.append(df2).append(df3)
  • combin_first 数据填补

使用场景:有两张表left和right,一般要求它们的表格结构一致,数据量也一致,使用right的数据去填补left的数据缺漏 如果在同一位置left与right数据不一致,保留left的数据

df1.combin_first(df2)

groupby

个人认为一张非常经典的图片

这里写图片描述
这里写图片描述

pandas提供了一个灵活高效的groupby功能,它使你能以一种自然的方式对数据集进行切片、切块、摘要等操作。根据一个或多个键(可以是函数、数组或DataFrame列名)拆分pandas对象。计算分组摘要统计,如计数、平均值、标准差,或用户自定义函数。对DataFrame的列应用各种各样的函数。应用组内转换或其他运算,如规格化、线性回归、排名或选取子集等。计算透视表或交叉表。执行分位数分析以及其他分组分析。

In [124]: df = pd.DataFrame({'key1':['a', 'a', 'b', 'b', 'a'],^M
     ...: ...     'key2':['one', 'two', 'one', 'two', 'one'],^M
     ...: ...     'data1':[1,2,3,4,5],^M
     ...: ...     'data2':[6,7,8,9,10]})

In [125]: df
Out[125]:
   data1  data2 key1 key2
0      1      6    a  one
1      2      7    a  two
2      3      8    b  one
3      4      9    b  two
4      5     10    a  one
#-------------------------------------------------------------
In [126]: grouped=df['data1'].groupby(df['key1'])

In [127]: grouped
Out[127]: <pandas.core.groupby.SeriesGroupBy object at 0x000001589EE04C88>
#变量grouped是一个GroupBy对象,它实际上还没有进行任何计算,只是含有一些有关分组键df['key1']的中间数据而已,
#然后我们可以调用GroupBy的mean(),sum(),size(),count()等方法,索引为key1列中的唯一值

In [128]: grouped.sum()
Out[128]:
key1
a    8
b    7
Name: data1, dtype: int64

In [129]: grouped.count()
Out[129]:
key1
a    3
b    2
Name: data1, dtype: int64

In [130]: grouped.size()
Out[130]:
key1
a    3
b    2
dtype: int64

In [131]: grouped.mean()
Out[131]:
key1
a    2.666667
b    3.500000
Name: data1, dtype: float64
#-------------------------------------------------------------

#一次传入多个数组,就会得到不同的结果:
In [132]: df['data1'].groupby([df['key1'], df['key2']]).mean()
Out[132]:
key1  key2
a     one     3
      two     2
b     one     3
      two     4
Name: data1, dtype: int64

#unstack()
In [133]: df['data1'].groupby([df['key1'], df['key2']]).mean().unstack()
Out[133]:
key2  one  two
key1
a       3    2
b       3    4

In [134]: df.groupby('key1').mean()
Out[134]:
         data1     data2
key1
a     2.666667  7.666667
b     3.500000  8.500000
#在执行df.groupby('key1').mean()时,结果中没有key2列。这是因为df['key2']不是数值数据,
#所以被从结果中排除了。默认情况下,所有数值列都会被聚合,虽然有时可能会被过滤为一个子集。
#-------------------------------------------------------------

#size()和count()的区别
In [144]: df2
Out[144]:
   data1  data2 key1 key2  data3
0      1      6    a  one    1.0
1      2      7    a  two    2.0
2      3      8    b  one    3.0
3      4      9    b  two    4.0
4      5     10    a  one    NaN

In [145]: df2.groupby(['key1', 'key2']).count()
Out[145]:
           data1  data2  data3
key1 key2
a    one       2      2      1
     two       1      1      1
b    one       1      1      1
     two       1      1      1

In [146]: df2.groupby(['key1', 'key2']).size()
Out[146]:
key1  key2
a     one     2
      two     1
b     one     1
      two     1
dtype: int64

时间操作
  • Python标准模块 datetime data:表示日期的类,常用的属性有year, month, day time:表示时间的类,常用的属性有hour, minute, second, microsecond, tzinfo datetime:表示日期时间,常用的属性有year, month, day, hour, minute, second, microsecond, tzinfo timedelta:表示时间间隔,即两个时间点之间的长度 tzinfo: 与时区有关的相关信息。 除了5种类以外,datetime模块还定义了两个常量:datetime.MINYEAR和datetime.MAXYEAR,分别表示datetime所能表示的最小、最大年份。其中,MINYEAR = 1,MAXYEAR = 9999。
from datetime import datetime
from datetime import timedelta

In [76]: now=datetime.now()
In [77]: now
Out[77]: datetime.datetime(2017, 3, 30, 11, 1, 46, 831048)
In [79]: now.year,now.month
Out[79]: (2017, 3)

In [91]: now
Out[91]: datetime.datetime(2017, 3, 30, 11, 1, 46, 831048)
In [92]: now+timedelta(12)
Out[92]: datetime.datetime(2017, 4, 11, 11, 1, 46, 831048)
  • 字符串和datetime的相互转换
In [94]: stamp=datetime(2017,3,28)
In [95]: stamp
Out[95]: datetime.datetime(2017, 3, 28, 0, 0)

In [96]: str(stamp)
Out[96]: '2017-03-28 00:00:00'

In [97]: stamp.strftime('%Y-%m-%d')
Out[97]: '2017-03-28'
  • pandas 的 TimeStamp对象(时间戳)
In [101]: pd.to_datetime(datetime(2017,3,28))
Out[101]: Timestamp('2017-03-28 00:00:00')

In [102]: pd.date_range('20160101','20160107')
Out[102]:
DatetimeIndex(['2016-01-01', '2016-01-02', '2016-01-03', '2016-01-04',
               '2016-01-05', '2016-01-06', '2016-01-07'],
              dtype='datetime64[ns]', freq='D')#默认按天

In [120]: pd.date_range('1/1/2010',periods=70,freq='H')#['2010-01-01 00:00:00' ,。。。,'2010-01-03 21:00:00'],              dtype='datetime64[ns]', freq='H')

移动(shifting)指的是沿着时间轴将数据前移或后移。Series 和 DataFrame 都有一个 .shift() 方法用于执行单纯的移动操作,index 维持不变:
  • pandas的时期(period) pd.Period 类的构造函数仍需要一个时间戳,以及一个 freq 参数。freq 用于指明该 period 的长度,时间戳则说明该 period 在公元时间轴上的位置。
In [108]: p=pd.Period(2010,freq='M')

In [109]: p
Out[109]: Period('2010-01', 'M')

In [110]:  pd.period_range('2010-01','2010-05',freq='M')
Out[110]: PeriodIndex(['2010-01', '2010-02', '2010-03', '2010-04', '2010-05'], dtype='period[M]', freq='M')
  • 时间戳与时期间相互转换
In [113]: ts = pd.Series(np.random.randn(4),index=pd.period_range('201001','201004',freq='M'))

In [114]: ts
Out[114]:
2010-01   -0.617026
2010-02   -2.939740
2010-03    0.695834
2010-04   -1.461667
Freq: M, dtype: float64

In [115]: ts.to_timestamp()
Out[115]:
2010-01-01   -0.617026
2010-02-01   -2.939740
2010-03-01    0.695834
2010-04-01   -1.461667
Freq: MS, dtype: float64

In [116]: ts.to_timestamp(how='end')
Out[116]:
2010-01-31   -0.617026
2010-02-28   -2.939740
2010-03-31    0.695834
2010-04-30   -1.461667
Freq: M, dtype: float64

In [117]: ts.to_timestamp().to_period()
Out[117]:
2010-01   -0.617026
2010-02   -2.939740
2010-03    0.695834
2010-04   -1.461667
Freq: M, dtype: float64

In [118]: ts.to_timestamp().to_period('D')
Out[118]:
2010-01-01   -0.617026
2010-02-01   -2.939740
2010-03-01    0.695834
2010-04-01   -1.461667
Freq: D, dtype: float64
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年03月30日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 多表操作
  • groupby
  • 时间操作
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档