Bootstrap

Python数据分析—Pandas中的DataFrame笔记全

一、DataFrame介绍

DataFrame是二维数组,表示的是矩阵的数据表,它包含已排序的列集合,每一列可以是不同的值类型(数值,字符串,布尔值)。

二、DataFrame数组创建

pd.DataFrame(data=None,index=None,columns=None,dtype=None,copy=False)

1、指定行索引 index ,列索引columns

(不指定为默认值 0 1 2……)

d1=pd.DataFrame(np.arange(9).reshape(3,3),index=['a','b','c'],columns=['A','B','C'])
d1
    A   B   C
a	0	1	2
b	3	4	5
c	6	7	8

2、根据字典创建

data={
     'name':['Python','Java','R'],
     'age':[18,20,22],
     'sex':['M','F','M']
    }
d2=pd.DataFrame(data)
d2
     name  age sex
0	Python	18	M
1	Java	20	F
2	R	    22	M

指定的列索引如果与字典中一致,只是顺序不同,则按指定的顺序排放

pd.DataFrame(data,columns=['age','name','sex'])
    age  name  sex
0	18	Python	M
1	20	Java	F
2	22	R	    M

指定的列索引少于字典中的键值数据时,以指定的为主

pd.DataFrame(data,columns=['name','age'])
    name    age
0	Python	18
1	Java	20
2	R	    22

指定的列索引多于字典中的键值数据时,会自动补齐NAN

pd.DataFrame(data,columns=['name','age','what','why'])
    name   age  what why
0	Python	18	NaN	NaN
1	Java	20	NaN	NaN
2	R	    22	NaN	NaN

当字典的数据完全不一致时,缺失的部分也会自动补齐NAN。(且NAN为浮点数,所以存在NAN的该列自动转为了浮点数)

data1=[
    {'name':'Python','age':18,'sex':'F'},
    {'name':'Java','sex':'M'},
    {'name':'R','age':20}
]
d3=pd.DataFrame(data1)
d3
    name    age    sex
0	Python	18.0	F
1	Java	NaN	    M
2	R	    20.0	NaN

三、DataFrame基础操作

操作意义
df.shape查看数组形状,返回值为元组
df.dtypes查看列数据类型 ( 因每列数据类型可以不一致,所以要加 s )
df.ndim数据维度,返回为整数
df.index行索引
df.columns列索引
df.values
df.head(n)显示头部几行,默认前5行
df.tail(n)显示末尾几行,默认后5行
df.info()相关信息

四、重置索引

1、重置行索引 df.reindex(index)

如果重置的索引与df中指定的index无关,则全部填充为NAN

d1.reindex([1,2,3])
    A   B   C
1	NaN	NaN	NaN
2	NaN	NaN	NaN
3	NaN	NaN	NaN

如果重置的索引与df中指定的index完全一致,只是顺序不同,则按重置的排

d1.reindex(['b','c','a'])
    A   B   C
b	3	4	5
c	6	7	8
a	0	1	2

如果重置的索引比df中指定的index多,则多出的部分填充NAN

d1.reindex(['a','b','c','d'])
    A    B    C
a	0.0	1.0	2.0
b	3.0	4.0	5.0
c	6.0	7.0	8.0
d	NaN	NaN	NaN

可使用 fill_value 参数修改填充值

d1.reindex(['a','b','c','d'],fill_value=0)
    A   B   C
a	0	1	2
b	3	4	5
c	6	7	8
d	0	0	0

2、重置列索引 df.reindex(columns=)

上述操作与行索引一致

同时重置行索引和列索引

d1.reindex(index=['b','c','a'],columns=['B','C','A'])
    B   C   A
b	4	5	3
c	7	8	6
a	1	2	0

五、索引与切片

d4=pd.DataFrame(
   [{'name':'python','age':18,'sex':'F'},
   {'name':'java','age':20,'sex':'M'},
   {'name':'c','age':22,'sex':'F'},
   {'name':'python','age':18,'sex':'F'},
   {'name':'java','age':20,'sex':'F'}],
   index=['a','b','c','d','e']
)
d4
    name    age sex
a	python	18	F
b	java	20	M
c	c	22	F
d	python	18	F
e	java	20	F

1、通过行索引筛选数据

注意:标签取行是双闭合区间

d4[:2]     # 索引取行
d4[:'b']   # 标签取行
# d4['b'] 会默认以为是列索引,取行索引会报错

2、通过列索引筛选数据

d4['name']
d4.name

3、递归取行列

取前两行的 ‘name’ 值

d4[:2]['name']
d4.name[:2]

4、布尔索引取值

取name中不含java的值

d4[d4.name != 'java']

若数组数据全为数值,假设取出大于4的数,则小于4的数会填充为NAN

d5=pd.DataFrame(np.arange(9).reshape(3,3),columns=['name','age','sex'])
d5[d5 > 4]
   name age sex
0	NaN	NaN	NaN
1	NaN	NaN	5.0
2	6.0	7.0	8.0

5、loc 及 iloc查询

df.loc[ ] 通过轴标签选择数据

# 取'a'这一行
d4.loc['a',:]
d4.loc['a']
# 取'name'这一列
d4.loc[:,'name']
# 神奇索引取'a'和'd'两行
d4.loc[['a','d'],:]
# 神奇索引取'name'和'sex'两列
d4.loc[:,['name','sex']]
# 取连续行'b'到'd'
d4.loc['b':'d',:]
# 取连续列'name'到'age'
d4.loc[:,'name':'age']

df.iloc[ ] 通过整数索引选择数据

# 取'b'这一行
d4.iloc[1,:]
d4.iloc[1]
# 取'name'这一列
d4.iloc[:,0]
# 神奇索引取'a'和'd'两行
d4.iloc[[0,3],:]
# 神奇索引取'name'和'sex'两列
d4.iloc[:,[0,2]]
# 取连续行'a'到'b'
d4.iloc[0:2]
# 取连续列'name'到'age'
d4.iloc[:,0:2]
# 取出'name'到'age' 且age大于18的数据
d4.iloc[:,0:2][d4.age > 18]

六、修改数据

# 修改'age'整列的数据
d4.age=[1,2,3,4,5]
# 修改'b'整行的数据
d4.loc['b']=[7,8,9]
# 修改第'b'行'age'列的数据
d4.loc['b','age']=10

七、新增数据

1、插入列

# 直接插入列
d4['like']=10
# 在第0列前插入'yes'列,并指定数据
d4.insert(0,'yes',[6,6,6,6,6])
# 在第0列前再次插入'yes'列,设置allow_duplicates=True参数允许重复,否则报错
d4.insert(0,'yes',[6,6,6,6,6],allow_duplicates=True)

2、添加行

用append方法添加行,类似于数组的拼接,但添加行的列索引必须与所拼接的列索引一致

dd=pd.DataFrame(np.arange(6).reshape(1,6),index=['w'],columns=d4.columns)
d5=d4.append(dd)
d5
    yes yes name  age  sex  like
a	6	6	python	1	F	10
b	6	6	7	10	9	10
c	6	6	c	3	F	10
d	6	6	python	4	F	10
e	6	6	java	5	F	10
w	0	1	2	3	4	5

八、删除数据

1、del删除

del删除的只能是列,不能是行

del d4['name']

2、drop()删除

drop可以设置删除行、列

# 删除行
d4.drop(index=['b','d'])
# 删除列
d4.drop(columns=['name'])

也可以通过指定axis轴来确定删除行、列
默认删除行(axis=0)

# 删除行
d4.drop('a',axis=0)
# 删除列
d4.drop('age',axis=1)
# 以上操作均不改变原数据,指定inplace=True改变原数据
d4.drop('age',axis=1,inplace=True)

九、数组计算

DataFrame与DataFrame进行计算时,索引相同的部分进行运算,缺失部分填充NAN

d1=pd.DataFrame(np.ones((2,2)),columns=['a','b'])
d2=pd.DataFrame(np.ones((3,3)),columns=['a','b','c'])
d1 + d2
     a   b   c
0	2.0	2.0	NaN
1	2.0	2.0	NaN
2	NaN	NaN	NaN

DataFrame与Series进行计算时,索引相同会进行0轴广播

# 取第0行
s=d2.iloc[0] 
d2 + s
     a   b   c
0	2.0	2.0	2.0
1	2.0	2.0	2.0
2	2.0	2.0	2.0

索引不同则取并集,其余填充NAN

ss=pd.Series(np.ones(3))
d2 + ss
     a   b   c   0   1   2
0	NaN	NaN	NaN	NaN	NaN	NaN
1	NaN	NaN	NaN	NaN	NaN	NaN
2	NaN	NaN	NaN	NaN	NaN	NaN

使用add方法进行计算,方法中可用 fill_value 填充值

d1.add(d2,fill_value=2)
     a   b   c  
0	2.0	2.0	3.0
1	2.0	2.0	3.0
2	3.0	3.0	3.0

fill_value填充方法如下:
在这里插入图片描述
使用填充值的算术方法有:

方法描述
add加法(+)
sub减法(-)
div除法(/)
floordiv整除(//)
mul乘法(*)
pow幂次方(**)

描述性统计计算方法:

方法描述
describe查看统计结果
count非NA值的个数
min,max最小值,最大值
idxmin,idxmax最小值,最大值的标签索引
sum求和
mean平均数
median中位数
var方差
std标准差
cumsum累计值
cummin,cummax累计值的最小值或最大值
cumprod值的累计积
diff差值(后一个数减前一个数)
pct_change增长率(后-前)/前
corr相关系数
cov协方差

注:sum函数默认跳过NA,如拒绝跳过NA,需设置skipna=False

可以用aggregate自定义聚合函数

d2.aggregate((np.sum,np.mean,np.min))
         a   b   c
sum	    3.0	3.0	3.0
mean	1.0	1.0	1.0
amin	1.0	1.0	1.0

十、排序

1、索引排序

df=pd.DataFrame(np.arange(12).reshape(3,4))
# 默认是升序,默认轴为0轴
df.sort_index()
# 降序
df.sort_index(ascending=False)
# 根据1轴降序
df.sort_index(ascending=False,axis=1)

如果索引是字符串,则根据ascii码排序

df2=pd.DataFrame(np.arange(12).reshape(3,4),index=['b','c','a'],columns=['a','b','c','d'])
df3=df2.sort_index()
    a   b   c   d
a	8	9	10	11
b	0	1	2	3
c	4	5	6	7

2、值排序

值排序必须指定by参数,默认为升序

df3.sort_values(by='b')
df3.sort_values(by='b',ascending=False)  # 降序

如果多列排序,排序键存在优先级

df3.iloc[1,0]=4
df3.iloc[1,1]=10
df3.sort_values(by=['a','b'])

先根据a列升序,如果有相同值,相同位置根据b列的升序来

    a   b   c   d
c	4	5	6	7
b	4	10	2	3
a	8	9	10	11

注:排序后是整行整列的变动,不是单个值的变动

十一、数组的映射

1、map()方法

生成数组

df = pd.DataFrame({"Country Name":["China","France","UK","US"]})
country_dict = {
    "China":"中国",
    "UK":"英国",
    "France":"法国",
    "US":"美国"
}

若想在df中新增一列中文与之对应
使用map()方法只能作用于Series对象,不能是DataFrame

df["国家"] = df["Country Name"].map(country_dict)
 Country Name 国家
0	China	  中国
1	France	  法国
2	UK	      英国
3	US	      美国

2、df.apply()

需传入一个函数

df2 = pd.DataFrame(np.random.uniform(-10,10,size=(4,4)))
# 定义匿名函数,求每行的最大值
f = lambda x:x.max()
# 通过函数逐个返回每行的最大值,默认axis=0
df2.apply(f,axis=1)

3、df.applymap()

函数应用到每个数据上

# 保留两位小数
f2 = lambda x:"%.2f"%x
# 或 f2=lambda x:round(x,2)
df2.applymap(f2)

DataFrame到此就结束了,还需反复咀嚼才能熟记于心

;