数据分析之pandas

系列文章目录


前言


提示:以下是本篇文章正文内容,下面案例可供参考

一、pandas是什么?

pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

二 数据表基本用法(一)

1.数据表创建

A.一维情形Series,创建Series对象可以通过传入list列表,dic字典或者numpy的nadarry对象

A.通过list创建
代码如下(示例):

>>> import pandas as pd
>>>> pd.Series([5,6,7,8,9])	#传入列表参数
0    5
1    6
2    7
3    8
4    9
dtype: int64
>>> s=pd.Series([5,6,7,8,9])
>>> s.values
array([5, 6, 7, 8, 9])	#获得值,返回一个numpy数组
>>> s.index	#获得索引,返回一个numpy数组
RangeIndex(start=0, stop=5, step=1)

代码如下(示例):创建一个具有时间目录(pd.date_range())的Series

>>> pd.date_range('20210316',periods=5)#首先获得一个想要的时间索引
DatetimeIndex(['2021-03-16', '2021-03-17', '2021-03-18', '2021-03-19',
               '2021-03-20'],
              dtype='datetime64[ns]', freq='D')
#传入此索引,打印如下
>>> s2=pd.Series(range(1,6),index=pd.date_range('20210316',periods=5))
>>> s2
2021-03-16    1
2021-03-17    2
2021-03-18    3
2021-03-19    4
2021-03-20    5
Freq: D, dtype: int64 #‘Freq’的值为D,代表频率为‘day’天

B.通过numpy对象创建
代码如下(示例):使用numpy对象创建Series

>>> import numpy as np
>>> s = pd.Series( np.array([27.2, 27.65, 27.70, 28, 28, np.nan]) )
>>> s
0    27.20
1    27.65
2    27.70
3    28.00
4    28.00
5      NaN
dtype: float64
>>> len(s)
6
>>> s.shape
(6,)
>>> s.count

C.通过字典dic创建
代码如下(示例):使用字典创建Series

>>> data_dict = { 'BABA': 187.07, 'PDD': 21.83, 'JD': 30.79, 'BIDU': 184.77 }
>>>> s3=pd.Series(data_dict,name='中概股')
>>>> s3.index.name='股票代号'
>>>> s3
股票代号
BABA    187.07
PDD      21.83
JD       30.79
BIDU    184.77
Name: 中概股, dtype: float64

B.二维情形,DataFrame

代码如下(示例):同样可以传递以上三个参数,list,dict和numpy对象,下面就以dict为例说明,可以发现,字典中的key成为DataFrame中的colums中的元素,index同样可以指定;

import pandas as pd
symbol = ['BABA', 'JD', 'AAPL', 'MS', 'GS', 'WMT']
data = {'行业': ['电商', '电商', '科技', '金融', '金融', '零售'],
        '价格': [176.92, 25.95, 172.97, 41.79, 196.00, 99.55],
        '交易量': [16175610, 27113291, 18913154, 10132145, 2626634, 8086946],
        '雇员': [101550, 175336, 100000, 60348, 36600, 2200000]}
df2 = pd.DataFrame( data , index=symbol)
df2.name='美股'
df2.index.name = 'Name'
>>> s
      行业      价格       交易量       雇员
Name                               
BABA  电商  176.92  16175610   101550
JD    电商   25.95  27113291   175336
AAPL  科技  172.97  18913154   100000
MS    金融   41.79  10132145    60348
GS    金融  196.00   2626634    36600
WMT   零售   99.55   8086946  2200000
#高级操作,如下
>>> s.describe()
               价格           交易量            雇员
count    6.000000  6.000000e+00  6.000000e+00
mean   118.863333  1.384130e+07  4.456390e+05
std     73.748714  8.717312e+06  8.607522e+05
min     25.950000  2.626634e+06  3.660000e+04
25%     56.230000  8.598246e+06  7.026100e+04
50%    136.260000  1.315388e+07  1.007750e+05
75%    175.932500  1.822877e+07  1.568895e+05
max    196.000000  2.711329e+07  2.200000e+06

2.数据表存载

DataFrame 可以被保存为 Excel, csv, SQL 和 HDF5 格式,其语句一看就懂,用 to_数据格式,具体如下:

df = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6]]))
df.to_excel('pd_excel.xlsx', sheet_name='Sheet1')

如果要加载某种格式的数据到 DataFrame 里,用 read_数据格式,具体如下:

df1 = pd.read_excel('pd_excel.xlsx', sheet_name='Sheet1')
df1df1 = pd.read_excel('pd_excel.xlsx', sheet_name='Sheet1')
df1

3.数据表索引与切片

A.单元素索引

可以通过位置索引,也可以通过标签索引
代码如下(示例):

#以此DataFrame为例
      行业      价格       交易量       雇员
Name                               
BABA  电商  176.92  16175610   101550
JD    电商   25.95  27113291   175336
AAPL  科技  172.97  18913154   100000
MS    金融   41.79  10132145    60348
GS    金融  196.00   2626634    36600
WMT   零售   99.55   8086946  2200000
>>> s.iat[1,1]#用于位置索引
25.95
>>> s.at['JD','价格']#用于坐标索引
25.95
>>> s.价格
Name
BABA    176.92
JD       25.95
AAPL    172.97
MS       41.79
GS      196.00
WMT      99.55
Name: 价格, dtype: float64
>>> s['价格']
Name
BABA    176.92
JD       25.95
AAPL    172.97
MS       41.79
GS      196.00
WMT      99.55
Name: 价格, dtype: float64

B.列切片

>>> s.loc[:, '交易量':'交易量']#使用loc,返回一个DataFrame
           交易量
Name          
BABA  16175610
JD    27113291
AAPL  18913154
MS    10132145
GS     2626634
WMT    8086946
>>> s.loc[:, '交易量']#使用loc,返回一个Series
Name
BABA    16175610
JD      27113291
AAPL    18913154
MS      10132145
GS       2626634
WMT      8086946
Name: 交易量, dtype: int64
>>> s.iloc[:, 0:2]#使用iloc,返回一个DataFrame,同样也可以返回一个Series
      行业      价格
Name            
BABA  电商  176.92
JD    电商   25.95
AAPL  科技  172.97
MS    金融   41.79
GS    金融  196.00
WMT   零售   99.55

三 数据表基本用法(二)

1.数据表合并与连接

A.数据表合并

pandas.merge()函数是pandas提供的一种数据库风格的合并函数

代码如下(示例):

#用以下两个DataFrame为例进行合并
>>> df_price = pd.DataFrame( {'Date': pd.date_range('2021-3-31', periods=4),
                          'Adj Close': [24.42, 25.00, 25.25, 25.64]})
>>> df_price
        Date  Adj Close
0 2021-03-31      24.42
1 2021-04-01      25.00
2 2021-04-02      25.25
3 2021-04-03      25.64

>>> df_volume = pd.DataFrame( {'Date': pd.date_range('2021-3-31', periods=5),
                           'Volume' : [56081400, 99455500, 83028700, 100234000, 73829000]})
>>> df_volume
        Date     Volume
0 2021-03-31   56081400
1 2021-04-01   99455500
2 2021-04-02   83028700
3 2021-04-03  100234000
4 2021-04-04   73829000

利用pd.merge()的‘how’变量进行合并,pd.merge(how{‘left’, ‘right’, ‘outer’, ‘inner’, ‘cross’}, default ‘inner’),默认为‘inner’,下面是outer的示例,其他可以自行尝试;


>>> pd.merge(df_volume,df_price,how='outer')
        Date     Volume  Adj Close
0 2021-03-31   56081400      24.42
1 2021-04-01   99455500      25.00
2 2021-04-02   83028700      25.25
3 2021-04-03  100234000      25.64
4 2021-04-04   73829000        NaN

B.数据表连接

pandas.concat(objs, axis=0, join=‘outer’)函数用于数据表连接,注意传入的对象必须是列表类型,默认沿着竖直方向连接,方式为‘inner’(取交集),当取‘outer’取并集
代码如下(示例):

>>> s1 = pd.Series(['a', 'b'])
>>> s2 = pd.Series(['c', 'd'])
>>> pd.concat([s1,s2])#默认竖直方向连接,得到更长的Series
0    a
1    b
0    c
1    d
dtype: object
>>> pd.concat([s1,s2],ignore_index=True)#不考虑之前的索引
0    a
1    b
2    c
3    d
dtype: object
>>> pd.concat([s1,s2],keys=['one','two'])#使用keys,建立多层Series
one  0    a
     1    b
two  0    c
     1    d
dtype: object

>>> df1=pd.DataFrame(np.arange(1,17).reshape(4,4),columns=['a','b','c','d'])
    a   b   c   d
0   1   2   3   4
1   5   6   7   8
2   9  10  11  12
3  13  14  15  16
>>> df2=pd.DataFrame(np.arange(1,10).reshape(3,3),columns=['a','b','c'])
   a  b  c
0  1  2  3
1  4  5  6
2  7  8  9
>>> pd.concat([df1,df2])#默认竖直方向合并,即列标签补齐,再纵向连接
    a   b   c     d
0   1   2   3   4.0
1   5   6   7   8.0
2   9  10  11  12.0
3  13  14  15  16.0
0   1   2   3   NaN
1   4   5   6   NaN
2   7   8   9   NaN
>>> pd.concat([df1,df2],ignore_index=True)##不考虑之前的索引
    a   b   c     d
0   1   2   3   4.0
1   5   6   7   8.0
2   9  10  11  12.0
3  13  14  15  16.0
4   1   2   3   NaN
5   4   5   6   NaN
6   7   8   9   NaN

1.数据表重塑与透视

A.重塑

数据表重塑是指变换数据表行,列索引,重现数据表,重塑层次化索引(多层索引);
重塑通过使用 pd.stack() 和 pd.unstack() 函数 (互为逆转操作)来实现

DataFrame.stack

pd.stack()(堆叠)
Stack the prescribed level(s) from columns to index.
此函数将‘列’中的数据堆叠到‘行’目录中,也就是旋转到‘行’目录
之下

代码如下(示例):

#以DataFrame为例说明

>>> df_single_level_cols = pd.DataFrame([[0, 1], [2, 3]]
                ,index=['cat', 'dog']
                ,columns=['weight', 'height'])
>>> df_single_level_cols.index.name='Name'
>>> df_single_level_cols.columns.name='Paras'
>>> df_single_level_cols
Paras  weight  height
Name                 
cat         0       1
dog         2       3
>>> df_single_level_cols.stack()
#使用堆叠函数,列索引将从属行索引
>>> df_single_level_cols.stack()
Name  Paras 
cat   weight    0
      height    1
dog   weight    2
      height    3
dtype: int64
>>> type(df_single_level_cols.stack())
<class 'pandas.core.series.Series'>

我们看到对DataFrame使用pd.stack()函数,最终使得原DataFrame重塑成了Series,原来的二维数据表变成了一个多层Series;

pd.unstack()(拆堆)
Pivot(旋转) a level of the (necessarily hierarchical(分等级的)) index labels.
此函数将‘行’中的数据拆堆到‘列’目录中,也就是旋转到‘列’目录
之下

DataFrame.ustack


>>> df2=df_single_level_cols.unstack()
Paras   Name
weight  cat     0
        dog     2
height  cat     1
        dog     3
dtype: int64
>>> type(df2)
<class 'pandas.core.series.Series'>

我们看到对DataFrame使用pd.unstack()函数,最终使得原DataFrame也重塑成了Series,原来的二维数据表同样也变成了一个多层Series;

尚若继续对拆堆后得到的Series再次进行拆堆,我们得到下图结果,上面的df2的‘行’目录分为两层:‘Paras’层和‘Name’层,若没有选择哪一层进行拆堆,则默认选择最后一层,所以‘Name’成为列目录;选择‘0’则代表使用第一层;当然也可以是用各个层定义的名称如’Name‘和’Paras‘进行拆堆

>>> df2.unstack()#未指定层数进行拆堆
Name    cat  dog
Paras           
weight    0    2
height    1    3
>>> df2.unstack(0)#指定层数进行拆堆
Paras  weight  height
Name                 
cat         0       1
dog         2       3

B.透视

DataFrame.pivot

数据表透视用于调整源表的布局用作更清晰的展示,多个时间序列数据(在多个时间点观察或测量到的数据)通常是以所谓的“长格式”(long)或“堆叠格式”(stacked)存储在数据库和CSV中的,呈现出来则是纵向非常长的数据表,为了更好的展示数据,则可以借用pivot()方法进行处理

关系型数据存储数据正如上图所示,Date和Symbol通常就是主键(关系型数据库中的术语,是表中的一个或多个字段,它的值用于唯一地标识表中的某一条记录),不仅提供了关系完整性,而且提供了更为简单的查询支持。有的情况下,使用这样的数据会很麻烦,你可能会更喜欢不同的Symbol值分别形成一列,Date列中的时间戳则用作索引。DataFrame的pivot方法完全可以实现这个转换

代码如下(示例):

#创建二维数据表

>>> df1 = pd.DataFrame({'foo': ['one', 'one', 'one', 'two', 'two',
                           'two'],
                   'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
                   'baz': [1, 2, 3, 4, 5, 6],
                   'zoo': ['x', 'y', 'z', 'q', 'w', 't']})
>>> df1
   foo bar  baz zoo
0  one   A    1   x
1  one   B    2   y
2  one   C    3   z
3  two   A    4   q
4  two   B    5   w
5  two   C    6   t
>>> df1.pivot(index='foo',columns='bar',values='baz')
bar  A  B  C
foo         
one  1  2  3
two  4  5  6
#未指定values的值,则将所有除去目录(‘foo’和‘bar’)的列传入,并标出名称
>>> df1.pivot(index='foo',columns='bar')
    baz       zoo      
bar   A  B  C   A  B  C
foo                    
one   1  2  3   x  y  z
two   4  5  6   q  w  t

总结规律,可以看出,DataFrame的pivot方法其实很像数学上的合并同类项!

DataFrame.melt

DataFrame.pivot()方法的逆运算是pandas.melt,它合并多个列成为一个,产生一个比输入长的DataFrame。
DataFrame.melt(id_vars=None, value_vars=None, var_name=None, value_name=‘value’,ignore_index=True),这个方法主要用到上面的几个参数,id_vars代表目录,value_vars代表键名称,二者都可以接收列表,元组或数组数据类型

>>> df = pd.DataFrame({'A': {0: 'a', 1: 'b', 2: 'c'},
                   'B': {0: 1, 1: 3, 2: 5},
                   'C': {0: 2, 1: 4, 2: 6}})
>>> df.melt(id_vars=['A'],value_vars=['B'])
   A variable  value
0  a        B      1
1  b        B      3
2  c        B      5
>>> df.melt(id_vars=['A'],value_vars=['B','C'])
   A variable  value
0  a        B      1
1  b        B      3
2  c        B      5
3  a        C      2
4  b        C      4
5  c        C      6
>>> df.melt(id_vars=['A'], value_vars=['B'],
	var_name='myVarname', value_name='myValname')
	#指定名称
   A myVarname  myValname
0  a         B          1
1  b         B          3
2  c         B          5

四、pandas特殊操作

1.将行索引转化为列(reset_index())

>>> import pandas as pd
>>> df=pd.DataFrame({'A':[1,2,3],'B':[4,5,6]},index=['a','b','c'])
>>> df
   A  B
a  1  4
b  2  5
c  3  6
>>> df.reset_index()
  index  A  B
0     a  1  4
1     b  2  5
2     c  3  6

2.将列转化为行索引(set_index())

>>> df=pd.DataFrame({'A':[1,2,3],'B':[4,5,6]},index=['a','b','c'])
>>> df
   A  B
a  1  4
b  2  5
c  3  6
>>> df.set_index('A',inplace=True)
>>> df
   B
A   
1  4
2  5
3  6

3.将时间戳转化为字符串(strftime(’%Y-%m-%d’)方法)


>>>ls=[Timestamp('2021-01-22 00:00:00'),
 Timestamp('2021-01-21 00:00:00'),
 Timestamp('2021-01-20 00:00:00'),
 Timestamp('2021-01-19 00:00:00'),
 Timestamp('2021-01-18 00:00:00'),
 Timestamp('2021-01-17 00:00:00'),
 Timestamp('2021-01-16 00:00:00'),
 Timestamp('2021-01-15 00:00:00'),
 Timestamp('2021-01-14 00:00:00'),
 Timestamp('2021-01-13 00:00:00')]
 #结果输出如下
 >>>[x.strftime('%Y-%m-%d') for x in ls]
 ['2021-01-22',
 '2021-01-21',
 '2021-01-20',
 '2021-01-19',
 '2021-01-18',
 '2021-01-17',
 '2021-01-16',
 '2021-01-15',
 '2021-01-14',
 '2021-01-13']

4.时间格式转化为年,月,日,季度

参考pandas.Series.dt方法


df = pd.read_csv(r"spider.csv",header=None,names=['datetime','url','name','x','y'],encoding='utf-8')
df['datetime'] = pd.to_datetime(df['datetime'],errors='coerce')   #先转化为datetime类型,默认format='%Y-%m-%d %H:%M:%S'
df['date'] = df['datetime'].dt.date   #转化提取年-月-日
df['year'] =df['datetime'].dt.year.fillna(0).astype("int")   #转化提取年 ,
#如果有NaN元素则默认转化float64型,要转换数据类型则需要先填充空值,在做数据类型转换
df['month'] = df['datetime'].dt.month.fillna(0).astype("int")  #转化提取月
df['%Y_%m'] = df['year'].map(str) + '-' + df['month'].map(str) #转化获取年-月
df['day'] = df['datetime'].dt.day.fillna(0).astype("int")      #转化提取天
df['hour'] = df['datetime'].dt.hour.fillna(0).astype("int")    #转化提取小时
df['minute'] = df['datetime'].dt.minute.fillna(0).astype("int") #转化提取分钟
df['second'] = df['datetime'].dt.second.fillna(0).astype("int") #转化提取秒
df['dayofyear'] = df['datetime'].dt.dayofyear.fillna(0).astype("int") #一年中的第n天
df['weekofyear'] = df['datetime'].dt.weekofyear.fillna(0).astype("int") #一年中的第n周
df['weekday'] = df['datetime'].dt.weekday.fillna(0).astype("int") #周几,一周里的第几天,Monday=0, Sunday=6
df['quarter'] = df['datetime'].dt.quarter.fillna(0).astype("int") 

未完待续!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值