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到此就结束了,还需反复咀嚼才能熟记于心