【pandas】15 pandas数据结构
创始人
2024-05-11 12:48:46
0

【pandas】15 pandas数据结构

2023.1.13 总结来自https://mofanpy.com/tutorials/data-manipulation/pandas/
包括pandas数据结构Series/DataFrame;数据选取分类查询等内容

15.1 为什么需要pandas

  • 前面讲了numpy,我们发现,numpy主要用途就是对同一类数据进行处理,可以看成数据矩阵
  • Pandas 主要用于一维二维数据,但用于处理数据的功能也比较多,信息种类也更丰富,特别是你有一些包含字符的表格,Pandas 可以帮你处理分析这些字符型的数据表。
  • Pandas继承了numpy所有优点,但比numpy慢点

pandas中的数据是什么?

  • 数据序列Series
  • 数据表DataFrame

15.2 Series

Series核心就是一串类似于列表的序列。Pandas Series 为数据提供了一套索引。

pandas.Series( data, index, dtype, name, copy)

  • data:一组数据(ndarray 类型)。

  • index:数据索引标签,如果不指定,默认从 0 开始。

  • dtype:数据类型,默认会自己判断。

  • name:设置名称。

  • copy:拷贝数据,默认为 False。

1. 【列表转换】:列表外套个pd.Series() `

import pandas as pdl = [11,22,33]
s = pd.Series(l)
print(s)
0    11
1    22
2    33
dtype: int64

他这个pandas是按照excel表的习惯来的,一般数据一横行是一个数据,每个列是不同特征
所以这里面其实是三个数据,同一个特征数据,所以是3*1

2. 【index换索引】:'a’是字符串所以要‘’

s = pd.Series(l,index=['a',1,'c'])
print(s)
a    11
1    22
c    33
dtype: int64

3. 【字典创建】:最常规的创建,也是pandas的特色

s=pd.Series({"a":11,"b":22,'c':33})
s
a    11
b    22
c    33
dtype: int64

4. 转化成list,Series

print("array:", s.to_numpy())
print("list:", s.values.tolist())
array: [11 22 33]
list: [11, 22, 33]

【5. 访问】:5.1 单独访问 5.2 部分访问

  • 5.1 单独访问
s
0    11
1    22
2    33
dtype: int64
#通过索引访问
s[2]
33
s.at[2]
33
  • 5.2 部分访问:只需要指定需要数据的索引即可
pd.Series(s, index = [0, 2])
0    11
2    33
dtype: int64

6. name

import pandas as pdsites = {1: "Google", 2: "Runoob", 3: "Wiki"}myvar = pd.Series(sites, index = [1, 2], name="RUNOOB-Series-TEST" )print(myvar)
1    Google
2    Runoob
Name: RUNOOB-Series-TEST, dtype: object

15.3 数据表DataFrame

  1. pandas.DataFrame( data, index, columns, dtype, copy)
  • data:一组数据(ndarray、series, map, lists, dict 等类型)。

  • index:索引值,或者可以称为行标签。

  • columns:列标签,默认为 RangeIndex (0, 1, 2, …, n) 。

  • dtype:数据类型。

  • copy:拷贝数据,默认为 False。

  1. 横的叫row,竖的叫column

在这里插入图片描述

15.3.1 创建DataFrame数据

1. 【从二维list转成Dataframe】

df = pd.DataFrame([[1,2],[3,4]
])
df
01
012
134
  1. 【字典创建】:字典创建的key是列索引,这点和Series有区别,相当于属性;每行习惯看成一条完整的数据
df=pd.DataFrame({"col1":[1,3],"col2":[2,4]},index=["a","b"])
df
col1col2
a12
b34
  • index更改了行索引
  1. 【创建】:也可以把两个series拼起来
s=pd.DataFrame({"col1":pd.Series([1,2,6]),"col2":pd.Series([3,4])})
s
col1col2
013.0
124.0
26NaN
  • Series拼接方式索引无法直接更改】应该先拼接再更改
s=pd.DataFrame({"col1":pd.Series([1,2]),"col2":pd.Series([3,4])},index=["a","b"])
s
col1col2
aNaNNaN
bNaNNaN
  1. 更换行索引或列索引:.index.columns
s=pd.DataFrame({"'col1'":pd.Series([1,2]),"'col2'":pd.Series([3,4])})
s
'col1''col2'
013
124
s.index=['a','b']
s
'col1''col2'
a13
b24

*这里我们注意这相当于赋值,所以要用=

s.columns=[1,2]
s
12
a13
b24
  1. 【查看有哪些行或列索引】:df.index, df.columns
print(s)
#左闭右开
print(s.index, "\n")
print(s.columns)
   col1  col2
0     1   3.0
1     2   4.0
2     6   NaN
RangeIndex(start=0, stop=3, step=1) Index(['col1', 'col2'], dtype='object')

15.3.2 读取DataFrame数据

我们的思路主要两种:通过索引选取和通过位置选取

15.3.2.1 类似与读二维数组方法

import pandas as pd
import numpy as npdata = np.arange(-12, 12).reshape((6, 4))
df = pd.DataFrame(data, index=list("abcdef"), columns=list("ABCD"))
df
ABCD
a-12-11-10-9
b-8-7-6-5
c-4-3-2-1
d0123
e4567
f891011
  1. 【读某列】
df.A
a   -12
b    -8
c    -4
d     0
e     4
f     8
Name: A, dtype: int32
df["A"]
a   -12
b    -8
c    -4
d     0
e     4
f     8
Name: A, dtype: int32
  • 多选
df["A":"D"]
ABCD
df[["A","D"]]
AD
a-12-9
b-8-5
c-4-1
d03
e47
f811

多列选择。我们注意[]数量:多选时,切片就是单[],一个个用索引选的时候,是对两对[]

  1. 【读某行】
df["a":"a"]
ABCD
a-12-11-10-9
df["a":"b"]
ABCD
a-12-11-10-9
b-8-7-6-5
  1. 【读某值】:必须先列后行,否则报错
#两个条件
df["A"]["c"]
-4
  • 我们有时候也会看到.at的写法( 必须先行后列,否则报错

df.at["c","A"]
-4

15.3.2.2 通过索引选取:.loc

函数.loc是通过索引名字选取的

  • 用法和切片类似,[行,列]
  • 这里是当成Excel习惯的,所以是闭区间【c:d】,并非切片时左闭右开
import pandas as pd
import numpy as npdata = np.arange(-12, 12).reshape((6, 4))
df = pd.DataFrame(data, index=list("abcdef"), columns=list("ABCD"))
df
ABCD
a-12-11-10-9
b-8-7-6-5
c-4-3-2-1
d0123
e4567
f891011
df.loc["c":"d", "B":"D"]
BCD
c-3-2-1
d123
  • 访问某几行
print(df.loc["":"c"])
    A   B   C  D
a -12 -11 -10 -9
b  -8  -7  -6 -5
c  -4  -3  -2 -1
  • 某几列
print(df.loc[:,"B":"C"])
    B   C
a -11 -10
b  -7  -6
c  -3  -2
d   1   2
e   5   6
f   9  10

15.3.2.3 通过位置信息选取iloc

#这个是np类型的
data
array([[-12, -11, -10,  -9],[ -8,  -7,  -6,  -5],[ -4,  -3,  -2,  -1],[  0,   1,   2,   3],[  4,   5,   6,   7],[  8,   9,  10,  11]])
print("\ndf:\n", df.iloc[2:3, 1:3])
df:B  C
c -3 -2
print("\ndf:\n", df.iloc[[3, 1], :])
df:A  B  C  D
d  0  1  2  3
b -8 -7 -6 -5

15.2.3 loc和iloc混搭

row_labels = df.index[2:4]
print("row_labels:\n", row_labels)
col_labels = df.columns[[0, 3]]
print("col_labels:\n", col_labels)
print("\ndf:\n", df.loc[row_labels, col_labels])
row_labels:Index(['c', 'd'], dtype='object')
col_labels:Index(['A', 'B', 'C'], dtype='object')df:A  B  C
c -4 -3 -2
d  0  1  2

这里我们注意有几个[]

  • 用切片:就是1个【】,要单独表现几个行或列用两个【】

15.2.4 件过滤筛选

  • 选在 A Column 中小于 0 的那些数据
df
ABCD
a-12-11-10-9
b-8-7-6-5
c-4-3-2-1
d0123
e4567
f891011
df[df["A"]<0]
ABCD
a-12-11-10-9
b-8-7-6-5
c-4-3-2-1
df["A"]<0
a     True
b     True
c     True
d    False
e    False
f    False
Name: A, dtype: bool
  • 选在第一行数据不小于 -10 的数据

  • ~非的意思

print("~:\n", df.loc[:, ~(df.iloc[0] < -10)])
print("\n>=:\n", df.loc[:, df.iloc[0] >= -10])
~:C   D
a -10  -9
b  -6  -5
c  -2  -1
d   2   3
e   6   7
f  10  11>=:C   D
a -10  -9
b  -6  -5
c  -2  -1
d   2   3
e   6   7
f  10  11

15.3 多索引数据 Multi-Indexing

将数据记录在数据表时,特别是数据归类比较复杂的情况, 比如年级-班级-学生信息这种层级的记录,我们很可能要使用到合并单元格。 我们把这种模式叫做 Multi-Indexing 多索引。

15.3.1 构建Row多检索

  • 比如有两层分类,先输入一个分类检索,放到pd.MultiIndex.from_tuples
  • 创建DataFrame时候当index输入

方法1】:pd.MultiIndex.from_tuples()

  1. 设置分类

前面就是一个列表,然后变成MultiIndex

import pandas as pdtuples = [# 年级,班级("one", "1"),("one", "1"),("one", "2"),  ("one", "2"),("two", "1"),("two", "1"),("two", "2"),("two", "2"),
]
index = pd.MultiIndex.from_tuples(tuples, names=["grade", "class"])
index
MultiIndex([('one', '1'),('one', '1'),('one', '2'),('one', '2'),('two', '1'),('two', '1'),('two', '2'),('two', '2')],names=['grade', 'class'])
  1. 建数据时候 把这index导进去就行
s = pd.Series(["小米", "小明",      # 一年一班"小命", "小勉",      # 一年二班"小牛", "小鸟",      # 二年一班"小南", "小妮"       # 二年二班], name="name",index=index)
s
grade  class
one    1        小米1        小明2        小命2        小勉
two    1        小牛1        小鸟2        小南2        小妮
Name: name, dtype: object

方法2】:pd.MultiIndex.from_product()

这个有些规律 每个年级所在班级学生一样多。如下

import pandas as pditerables = [["one", "two"],  # 年级["1", "1", "2", "2"]  # 每个学生所在班级
]index2 = pd.MultiIndex.from_product(iterables, names=["grade", "class"])
index2
MultiIndex([('one', '1'),('one', '1'),('one', '2'),('one', '2'),('two', '1'),('two', '1'),('two', '2'),('two', '2')],names=['grade', 'class'])
s = pd.Series(["小米", "小明",      # 一年一班"小命", "小勉",      # 一年二班"小牛", "小鸟",      # 二年一班"小南", "小妮"       # 二年二班], name="name",index=index2)
s
grade  class
one    1        小米1        小明2        小命2        小勉
two    1        小牛1        小鸟2        小南2        小妮
Name: name, dtype: object

【方法3】pd.MultiIndex.from_frame(df):你的索引数据也维护在一张 DataFrame 中.其他一样

df = pd.DataFrame([# 年级,班级("one", "1"),("one", "1"),("one", "2"),("one", "2"),("two", "1"),("two", "1"),("two", "2"),("two", "2"),],columns=["grade", "class"]
)index3 = pd.MultiIndex.from_frame(df)
index3
MultiIndex([('one', '1'),('one', '1'),('one', '2'),('one', '2'),('two', '1'),('two', '1'),('two', '2'),('two', '2')],names=['grade', 'class'])

刚才都是Series。下面用DataFrame举例

df1 = pd.DataFrame({"id": [11,12,13,14,15,16,17,18],"name": ["小米", "小明",      # 一年一班"小命", "小勉",      # 一年二班"小牛", "小鸟",      # 二年一班"小南", "小妮"       # 二年二班]},index=index)
df1
idname
gradeclass
one111小米
112小明
213小命
214小勉
two115小牛
116小鸟
217小南
218小妮

15.3.2 构建Column多索引

df2 = pd.DataFrame([[11,12,13,14,15,16,17,18],["小米", "小明",      # 一年一班"小命", "小勉",      # 一年二班"小牛", "小鸟",      # 二年一班"小南", "小妮"       # 二年二班]],index=["id", "name"])
df2
01234567
id1112131415161718
name小米小明小命小勉小牛小鸟小南小妮

方法一样,其实里面他们是一一对应的,所以用columns引入多重索引就行

df2 = pd.DataFrame([[11,12,13,14,15,16,17,18],["小米", "小明",      # 一年一班"小命", "小勉",      # 一年二班"小牛", "小鸟",      # 二年一班"小南", "小妮"       # 二年二班]],index=["id", "name"],columns=index,  # 多索引加这
)
df2
gradeonetwo
class11221122
id1112131415161718
name小米小明小命小勉小牛小鸟小南小妮

15.3.3 选择数据

方法:就是用索引,很分类用.loc[];。列分类用类似二维数组的方法,每个【】是一个筛选条件

# 一个条件就是在one里的
df2["one"]
class1122
id11121314
name小米小明小命小勉
  • 列分类:两个条件,一个是在one里一个是在1里。特别注意这个1是字符串
#两个条件,一个是在one里一个是在1里。特别注意这个1是字符串
df2["one"]["1"]
class11
id1112
name小米小明
df4 = pd.DataFrame({"id": [11,12,13,14,15,16,17,18],"name": ["小米", "小明",      # 一年一班"小命", "小勉",      # 一年二班"小牛", "小鸟",      # 二年一班"小南", "小妮"       # 二年二班]},index=index)
df4
idname
gradeclass
one111小米
112小明
213小命
214小勉
two115小牛
116小鸟
217小南
218小妮
  • 行分类用.loc
#用loc
df4.loc["one"].loc["2"]
idname
class
213小命
214小勉

15.4 数据分组 Groupby

数据有关键词、每个数据带有特定类别?我们怎样可以快速找到对应的类别,聚类分析?groupby()

15.4.1 分组

  • df.groupby(); 按什么分类
  • grouped.groups;分类后每组得到索引
  • grouped.get_group()按什么分类后的数据
核心的功能,自然就是将可以被归纳的数据进行归纳汇总
import pandas as pddf = pd.DataFrame([("小红", "哈利波特", 80),("小明", "蜘蛛侠", 72),("小红", "雷神", 83),("小红", "蜘蛛侠", 45),("小明", "超人", 57),],columns=("人", "人物", "评价"),
)
df
人物评价
0小红哈利波特80
1小明蜘蛛侠72
2小红雷神83
3小红蜘蛛侠45
4小明超人57
# 这就把小名小红分成了两组
grouped = df.groupby("人")#可以查看分组后的索引
grouped.groups
{'小明': [1, 4], '小红': [0, 2, 3]}
  • 这就把小名小红分成了两组;可以查看分组后的索引;那么就可以做相应的操作
df.iloc[grouped.groups["小红"]]
人物评价
0小红哈利波特80
2小红雷神83
3小红蜘蛛侠45
  • 或者用函数,拿到分类后数据
grouped.get_group("小红")
人物评价
0小红哈利波特80
2小红雷神83
3小红蜘蛛侠45

15.4.2 调用分好的组

  • grouped.first(); 调用每个分类索引的第一个
  • grouped.last():调用每个分类索引的最后一个
grouped.first()
人物评价
小明蜘蛛侠72
小红哈利波特80
grouped.last()
人物评价
小明超人57
小红蜘蛛侠45

15.4.3 循环处理

有时候你想要对组进行循环处理,通过一个循环最所有组统一操作一下。那你需要注意一下这个 grouped 的循环,会带着两个字段做循环。 一个是组名,一个是组数据。

for name, group in grouped:print("name:", name)print(group)
name: 小明人   人物  评价
1  小明  蜘蛛侠  72
4  小明   超人  57
name: 小红人    人物  评价
0  小红  哈利波特  80
2  小红    雷神  83
3  小红   蜘蛛侠  45

15.4.4 多从分组

df = pd.DataFrame([("小红", "哈利波特", 80),("小明", "蜘蛛侠", 72),("小红", "雷神", 83),("小红", "雷神", 90),("小红", "蜘蛛侠", 45),("小明", "超人", 57),],columns=("人", "人物", "评价"),
)
df
人物评价
0小红哈利波特80
1小明蜘蛛侠72
2小红雷神83
3小红雷神90
4小红蜘蛛侠45
5小明超人57
df.groupby(["人", "人物"]).get_group(("小红", "雷神"))
人物评价
2小红雷神83
3小红雷神90
  • 以人 和人物 共同进行筛选

15.4.5 聚合计算

  • 如果有数据是数字 还能对数据进行sum, mean 等操作。
  • .agg() 其实是 .aggregate() 的缩写,都可以用

【方法1】

import numpy as np
grouped["评价"].agg([np.sum, np.mean, np.std])
summeanstd
小明12964.50000010.606602
小红20869.33333321.126603

【方法2】

print(grouped.sum())
print(grouped.mean())
print(grouped.std())
     评价
人      
小明  129
小红  208评价
人            
小明  64.500000
小红  69.333333评价
人            
小明  10.606602
小红  21.126603
  • 还有一个小技巧,如果你不喜欢用英文表达,或者你想要用另外一个名字来描述 column,你可以用 rename 来重新命名。
grouped["评价"].agg([np.sum, np.mean, np.std]
).rename(columns={"sum": "合", "mean": "均值", "std": "标准差"
})
均值标准差
小明12964.50000010.606602
小红20869.33333321.126603

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...