Series & DataFrame
# 概述
pandas 用于数据分析处理,基于 numpy。
pandas 一般适用于中小数据,单机处理。 Spark 一般适用于分布式处理。 但是可以将两者进行结合,在 spark 的每个 task 中使用 pandas 进行处理。
# 数据结构
pandas 两大数据结构:
- 一维的 Series: 一行或者一列, 怎么理解都对。
- 二维的 DataFrame: 由多个 Series 组成,是一个 sheet 表或者一个 table。 可以和 Spark 的 DF 相互转换。
DataFrame 是 Series 的容器,Series 则是标量的容器。使用这种方式,可以在容器中以字典的形式插入或删除对象。
Pandas 所有数据结构的值都是可变的,但数据结构的大小并非都是可变的,比如,Series 的长度不可改变,但 DataFrame 里就可以插入列。
Pandas 里,绝大多数方法都不改变原始的输入数据,而是复制数据,生成新的对象。 一般来说,原始输入数据不变更稳妥。
数据类型:
- float
- int
- bool
- datetime64[ns]
- datetime64[ns, tz]
- timedelta64[ns]
- timedelta[ns]: 两个时间之间的距离,时间差
- category: 枚举
- object: 文本或者混合数字
- string
构建 df:
pandas 特有数据类型:
- DatetimeTZDtype:带有时区的日期时间格式,
pd.DatetimeTZDtype("ns", tz="Asia/Shanghai")
- CategoricalDtype:有限的字符枚举类型,
pd.CategoricalDtype(categories=['male', 'female'])
- PeriodDtype:时间周期,
pd.PeriodDtype(freq=pd.offsets.Hour)
查看数据类型:
index = pd.Index(data=["Tom", "Bob", "Mary", "James"], name="name")
data = {
"age": [18, 30, 25, 40],
"city": ["BeiJing", "ShangHai", "GuangZhou", "ShenZhen"]
}
user_info = pd.DataFrame(data=data, index=index)
# <class 'pandas.core.frame.DataFrame'>
type(user_info)
# <class 'pandas.core.series.Series'>
type(user_info.age)
# <class 'pandas.core.series.Series'>
type(user_info.loc['Tom', :])
# Series
# 概述
Series 是一个带有名称和索引的一维数组, 但与列表不同的是,列表只能通过数字索引取值,而Series可以通过自定义索引取值,从这一点来看Series与字典类似。
pandas.Series(data=None, index=None, dtype=None, name=None, copy=False)
data:支持以下数据类型:
- Python 字典
- 多维数组
- 标量值(如,5)
index:索引,类似数组或列表,值必须是可哈希的,并且与 data 具有相同的长度。
允许使用非唯一索引值。
将默认为 RangeIndex(0,1,2,…,n)(如果未提供)。
如果 Index 和字典同时提供,index 将会覆盖字典的 keys。
dtype: str,numpy.d 类型,或 ExtensionType,可选输出序列的数据类型。如果未指定,则将从 data 推断。
name:Series 的名称。
copy: bool,默认为 False, 是否对输入数据进行复制。
# 增删改查
import pandas as pd
index = pd.Index(data=['Tom', 'Bob', 'Mary', 'James', 'Jack'], name='age')
data = [18, 30, 25, 40, None]
user_info = pd.Series(data=data, index=index, name='user_info')
'''
单个查询, 可用:
- user_info.Tom
- user_info['Tom']
- user_info.get('Tom'): 查询没有的数据不会报错, 只会返回 None
'''
user_info.get('Jack')
'''
索引查询, 可用:
- user_info[0]
- user_info[1:]: 切片查
- user_info[['Tom', 'Jack']]: 索引数组查询
- user_info[[0, 1]]: 索引序号查询
- user_info[user_info >= 30]: 布尔查询, 条件这里的 user_info 就是变量名, 或者 user_info[lambda x: x > 30]
'''
user_info[lambda x: x > 30]
# 元素添加和修改, 如果之前没有会添加, 之前有会修改
user_info['Macy'] = 27
'''
删除元素:
- del user_info['Wade']
- user_age.drop('Michael', inplace=False):
- 参数一可为数组, 一次删除多个数据.
- 默认 inplace 为 False 不改变原始数据, inplace 为 True 时改变原始数据.
'''
del user_info['Wade']
# 方法
- head(n):查看 Series 的前 n 个元素,默认 n 为5。
- tail(n):查看 Series 的后 n 个元素,默认 n 为5。
- unique():返回 Series 中不重复的元素。
- nunique(dropna=False):返回 Series 中不重复的元素个数。
- isna():判断元素是否是缺失值。
- isnull():和 isna() 功能相同。
- dropna(inplace=False):删除缺失值, inplace 为 True 时改变源数据。
- isin(values):成员运算,values 为 set 或者 list-like 类型,判断 series 中每个元素是否是 values 的成员。
- sort_index(ascending=False, inplace=False):对索引排序, inplace 为 True 时改变源数据.
- sort_values(ascending=False, inplace=False):对值排序, inplace 为 True 时改变源数据。
- idmax():返回最大值的索引。
- idmin():返回最小值的索引。
- nlargest():返回 n 个最大的值。
- nsmallest():返回 n 个最小的值。
- count():返回非缺失值元素个数。
- value_counts(ascending=False, dropna=True):统计数据频率, dropna 为 False 时计算缺失值。
- clip(lower, upper, inplace=False):对 Series 在 lower-upper 范围进行截断,小于 lower 的替换为lower, 大于 upper 的替换为 upper。
- replace(to_replace, value=None, inplace=False):对 Series 中指定值进行替换。
- where(cond, other=np.nan, inplace=False):对不满足 cond 的元素替换为 other。
- add_prefix(prefix):统一加前缀。
- add_suffix(suffix):统一加后缀。
- reset_index(drop=False, name=None, inplace=False):重置索引,当 drop 为 False 时返回 DataFrame。可以和 sort_values 一起使用.
- to_frame(name=None):将 Series 转换为 DataFrame。
- append(to_append, ignore_index=False, verify_integrity=False):将两个 Series 进行合并。
缺失值
缺失值不仅为 None,而且还有 numpy 的 nan,pandas 的 NA NAT:
None: 作为缺失值标签,它是一个 python 对象,它不能作为 Numpy / pandas 数组类型的缺失值,只能用于 object 数组类型(即由 python 对象构成的数组).
Series 类型为 object 时 None 才会为 None,其他类型时会转换成对应的数据类型,比如 bool 类型时会转换成 False,int 类型时会转换成 pd.nan
None == None
NaN: Not a Number,是在任何系统中都兼容的特殊浮点数
np.nan 是 numpy 和 pandas 中的缺失值表示,其自身数据类型为 float
np.nan 在 numpy 中的类型为浮点,由此导致数据集读入时,即使原来是整数的列,只要有缺失值就会变为浮点型
假如 bool 和 np.nan 同时出现,那 Series 会变为 object,如:
pd.Series([True, False, np.nan])
若强制设为 bool 类型,np.nan 会转为 True,如:
pd.Series([True, False, np.nan], dtype=bool)
但是修改一个 bool Series 时,会改变 Series 类型而不是将 np.nan 设为 True,如:
import pandas as pd import numpy as np series = pd.Series([True, False], dtype=bool) series[0] = np.nan ''' 0 NaN 1 False dtype: object ''' print(series)
np.nan != np.nan 且 np.nan != None 且 np.nan != 0
NaT: 是针对时间序列的缺失值,pandas 内置类型,特性与 np.nan 相同
Nullable: pandas 的类型,简称 NA,目的是为了统一前面的三种类型
好处就在于,其中前面提到的三种缺失值都会被替换为统一的 NA 符号,且不改变数据类型
对于缺失值的处理,加法看作 0,乘法看作 1,累计与统计函数时默认忽略,其他函数在默认情况下也有类似的处理情况
# DataFrame
# 概述
DataFrame 是个二维结构,不管是拆出一行还是一列,都是一个 Series
DataFrame 除了有 Series 中定义的 index 和 value 外,还有 column,需要定义到某个数据时,应该是 column -> index -> value
# 创建 DataFrame
字典套 Series
import pandas as pd
'''
从字典 Series 创建 DataFrame 时, 默认情况下会使用 Series 的 index 作为 DaraFrame 的 index
name age city
0 Tom 10 Beijing
1 Jack 20 Shanghai
2 Bob 30 Guangzhou
3 Mary 40 Shandong
'''
data = {
'name': pd.Series(['Tom', 'Jack', 'Bob', 'Mary']),
'age': pd.Series([10, 20, 30, 40]),
'city': pd.Series(['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'])
}
pd.DataFrame(data=data)
'''
如果 Series 和 DataFrame 同时指定 index, 那么 DataFrame 会根据自身的 index 去所有 Series 寻找值填到对应的位置, 找不到则为 NAN
name age city
Tom NaN NaN NaN
Jack NaN NaN NaN
0 Tom 10.0 Beijing
Mary NaN NaN NaN
'''
data = {
'name': pd.Series(['Tom', 'Jack', 'Bob', 'Mary']),
'age': pd.Series([10, 20, 30, 40]),
'city': pd.Series(['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'])
}
index = ['Tom', 'Jack', 0, 'Mary']
pd.DataFrame(data=data, index=index)
'''
columns 也一样, 如果指定的和开始定义的不同, 那么会找所有的 series 来填对应的值
name age hobby name
0 Tom 10 NaN Tom
1 Jack 20 NaN Jack
2 Bob 30 NaN Bob
3 Mary 40 NaN Mary
'''
columns = ['name', 'age', 'hobby', 'name']
data = {
'name': pd.Series(['Tom', 'Jack', 'Bob', 'Mary']),
'age': pd.Series([10, 20, 30, 40]),
'city': pd.Series(['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'])
}
pd.DataFrame(data=data, columns=columns)
字典套列表
import pandas as pd
'''
name age city
0 Tom 10 Beijing
1 Jack 20 Shanghai
2 Bob 30 Guangzhou
3 Mary 40 Shandong
'''
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong']
}
pd.DataFrame(data)
列表套字典
'''
name age
0 Tom 20
1 Jack 21
2 Rob 22
'''
data = [
{'name': 'Tom', 'age': 20},
{'name': 'Jack', 'age': 21},
{'name': 'Rob', 'age': 22}
]
df = pd.DataFrame(data)
列表套列表
import pandas as pd
'''
0 1 2 3
0 Tom Jack Bob Mary
1 10 20 30 40
2 Beijing Shanghai Guangzhou Shandong
'''
data = [
['Tom', 'Jack', 'Bob', 'Mary'],
[10, 20, 30, 40],
['Beijing', 'Shanghai', 'Guangzhou', 'Shandong']
]
pd.DataFrame(data)
from_dict
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong']
}
'''
将字典转为 DF
name age city
0 Tom 10 Beijing
1 Jack 20 Shanghai
2 Bob 30 Guangzhou
3 Mary 40 Shandong
'''
pd.DataFrame.from_dict(data)
'''
orient 可选 columns(默认), index. 当 orient='index' 时为行转列.
0 1 2 3
name Tom Jack Bob Mary
age 10 20 30 40
city Beijing Shanghai Guangzhou Shandong
'''
pd.DataFrame.from_dict(data, orient='index')
'''
指定 orient='index' 时可用 columns 指定列名称
A B C D
name Tom Jack Bob Mary
age 10 20 30 40
city Beijing Shanghai Guangzhou Shandong
'''
pd.DataFrame.from_dict(data, orient='index', columns=['A', 'B', 'C', 'D'])
from_records
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong']
}
'''
将结构化数据转为 DF
age city name
0 10 Beijing Tom
1 20 Shanghai Jack
2 30 Guangzhou Bob
3 40 Shandong Mary
'''
pd.DataFrame.from_records(data)
'''
exclude 可以排除列或者索引
city name
0 Beijing Tom
1 Shanghai Jack
2 Guangzhou Bob
3 Shandong Mary
'''
pd.DataFrame.from_records(data, exclude=['age'])
'''
可以选择列
name city
0 Tom Beijing
1 Jack Shanghai
2 Bob Guangzhou
3 Mary Shandong
'''
print(pd.DataFrame.from_records(data, columns=['name', 'city']))
文件读取
- read_csv:读取 csv 文件
- read_excel:读取 excel 文件
- read_html:读取 html 文件
- read_sql:读取 sql 数据
- read_json:读取 json 数据
# DataFrame 属性
- df.shape:查看形状
- df.columns:查看列名
- df.index:查看索引
- df.dtype:查看列数据类型
- df.ndim:查看数据维度
- df.T:转置
- df.values:将DataFrane转为数组类型
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong']
}
index = pd.Index(['A', 'B', 'C', 'D'], name='name')
'''
age city name
name
A 10 Beijing Tom
B 20 Shanghai Jack
C 30 Guangzhou Bob
D 40 Shandong Mary
'''
df = pd.DataFrame.from_records(data, index=index)
# 也就是几行几列, (4, 3)
df.shape
# 查看维度, 2
df.ndim
# Index(['A', 'B', 'C', 'D'], dtype='object', name='name')
df.index
# Index(['age', 'city', 'name'], dtype='object')
df.columns
'''
查看各列的 dtype
age int64
city object
name object
dtype: object
'''
df.dtypes
'''
查看 df 矩阵值
[[10 'Beijing' 'Tom']
[20 'Shanghai' 'Jack']
[30 'Guangzhou' 'Bob']
[40 'Shandong' 'Mary']]
'''
df.values
'''
df 转置
name A B C D
age 10 20 30 40
city Beijing Shanghai Guangzhou Shandong
name Tom Jack Bob Mary
'''
df.T
# DataFrame 方法
# 基础方法
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong']
}
index = pd.Index(['A', 'B', 'C', 'D'], name='name')
df = pd.DataFrame.from_records(data, index=index)
'''
查看前 n 行数据,默认为 5
age city name
name
A 10 Beijing Tom
B 20 Shanghai Jack
'''
df.head(2)
'''
查看后 n 行数据,默认为 5
age city name
name
C 30 Guangzhou Bob
D 40 Shandong Mary
'''
df.tail(2)
'''
查看整体情况
<class 'pandas.core.frame.DataFrame'>
Index: 4 entries, A to D
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 age 4 non-null int64
1 city 4 non-null object
2 name 4 non-null object
dtypes: int64(1), object(2)
memory usage: 128.0+ bytes
None
'''
df.info()
'''
选择特定类型的列
age
name
A 10
B 20
C 30
D 40
'''
df.select_dtypes(include='int64')
# 描述与统计
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
'sex': ['male', 'female', 'female', 'male'],
}
index = pd.Index(['A', 'B', 'C', 'D'], name='name')
df = pd.DataFrame.from_records(data, index=index)
'''
查看整体情况, 默认查看数字列的情况,可用 df.describe(include=['object']) 查看非数字列的统计情况
age
count 4.000000
mean 25.000000
std 12.909944
min 10.000000
25% 17.500000
50% 25.000000
75% 32.500000
max 40.000000
'''
df.describe()
'''
分组
[
(
'female',
age city name sex
name
B 20 Shanghai Jack female
C 30 Guangzhou Bob female
),
(
'male',
age city name sex
name
A 10 Beijing Tom male
D 40 Shandong Mary male
)
]
'''
[item for item in df.groupby('sex')]
'''
分组聚合统计
sex
female 50
male 50
Name: age, dtype: int64
'''
df.groupby('sex')['age'].sum()
'''
对某列的值进行频次统计
city
Beijing 1
Shanghai 1
Guangzhou 1
Shandong 1
Name: count, dtype: int64
'''
df['city'].value_counts()
# 离散化
import pandas as pd
'''
数据离散化其实就是将一组连续的数据切割到某几个范围中,形成离散化的数据
'''
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
'sex': ['male', 'female', 'female', 'male'],
}
index = pd.Index(['A', 'B', 'C', 'D'], name='name')
df = pd.DataFrame.from_records(data, index=index)
'''
根据年龄进行数据的离散化,自动将数据分为三部分:9.97 - 20、20 - 30、30 - 40
name
A (9.97, 20.0]
B (9.97, 20.0]
C (20.0, 30.0]
D (30.0, 40.0]
Name: age, dtype: category
Categories (3, interval[float64, right]): [(9.97, 20.0] < (20.0, 30.0] < (30.0, 40.0]]
'''
pd.cut(df.age, 3)
'''
手动分为三组
name
A (1, 20]
B (1, 20]
C (20, 30]
D (30, 40]
Name: age, dtype: category
Categories (3, interval[int64, right]): [(1, 20] < (20, 30] < (30, 40]]
'''
pd.cut(df.age, [1, 20, 30, 40])
'''
分为三组,并给三组起别名
name
A child
B child
C youth
D middle
Name: age, dtype: category
Categories (3, object): ['child' < 'youth' < 'middle']
'''
pd.cut(df.age, [1, 20, 30, 40], labels=['child', 'youth', 'middle'])
'''
pd.cut 根据每个值的大小进行分组,而 pd.qcut 根据每个值出现的次数进行分组
name
A (9.999, 20.0]
B (9.999, 20.0]
C (20.0, 30.0]
D (30.0, 40.0]
Name: age, dtype: category
Categories (3, interval[float64, right]): [(9.999, 20.0] < (20.0, 30.0] < (30.0, 40.0]]
'''
pd.qcut(df.age, 3)
# 排序
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
'sex': ['male', 'female', 'female', 'male'],
}
index = pd.Index(['D', 'B', 'C', 'A'], name='name')
df = pd.DataFrame.from_records(data, index=index)
'''
按序号进行排序
age city name sex
name
A 40 Shandong Mary male
B 20 Shanghai Jack female
C 30 Guangzhou Bob female
D 10 Beijing Tom male
'''
df.sort_index()
'''
按照 age 值进行倒序排
age city name sex
name
A 40 Shandong Mary male
C 30 Guangzhou Bob female
B 20 Shanghai Jack female
D 10 Beijing Tom male
'''
df.sort_values(by='age', ascending=False)
'''
多个字段进行排序排列
age city name sex
name
D 10 Beijing Tom male
C 30 Guangzhou Bob female
A 40 Shandong Mary male
B 20 Shanghai Jack female
'''
df.sort_values(by=['city', 'age'], ascending=True)
'''
直接获得最大的两个值,同理 nsmallest 直接获得最小的值
name
A 40
C 30
Name: age, dtype: int64
'''
df['age'].nlargest(2)
# 类型和类型转换
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
'sex': ['male', 'female', 'female', 'male'],
}
index = pd.Index(['D', 'B', 'C', 'A'], name='name')
df = pd.DataFrame.from_records(data, index=index)
'''
获得每列类型
age int64
city object
name object
sex object
dtype: object
'''
df.dtypes
'''
获得每个类型的统计信息
object 3
int64 1
Name: count, dtype: int64
'''
df.dtypes.value_counts()
'''
类型转换
name
D 10.0
B 20.0
C 30.0
A 40.0
Name: age, dtype: float64
'''
df['age'].astype(float)
# 索引行函数
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
'sex': ['male', 'female', 'female', 'male'],
}
index = pd.Index(['D', 'B', 'C', 'A'], name='name')
df = pd.DataFrame.from_records(data, index=index)
'''
不满足条件的默认会设为 NAN
age city name sex
name
D NaN NaN NaN NaN
B NaN NaN NaN NaN
C 30.0 Guangzhou Bob female
A 40.0 Shandong Mary male
'''
df.where(df['age'] > 20)
'''
不满足条件的全都设为填充值
age city name sex
name
D 20 20 20 20
B 20 20 20 20
C 30 Guangzhou Bob female
A 40 Shandong Mary male
'''
df.where(df['age'] > 20, 20)
'''
df.where(df['age'] > 20).dropna() 和 df[df['age'] > 20] 起到的作用完全一样,都是留下符合条件的值
'''
df.where(df['age'] > 20).dropna()
df[df['age'] > 20]
'''
mask 与 where 的功能相反,其余完全相同,即对符合条件的做 NAN,有填充则填充符合条件的数据
age city name sex
name
D 10.0 Beijing Tom male
B 20.0 Shanghai Jack female
C NaN NaN NaN NaN
A NaN NaN NaN NaN
'''
df.mask(df['age'] > 20)
'''
query 查询,支持如下符号:
- 行列索引名
- 字符串
- and、or、&、|、not、~
- ==、!=
- in、not in
- 四则运算符
age city name sex
name
A 40 Shandong Mary male
'''
df.query("(age > 20) & (city == 'Shandong')")
# 重复项处理
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
'sex': ['male', 'female', 'female', 'male'],
}
index = pd.Index(['D', 'B', 'C', 'A'], name='name')
df = pd.DataFrame.from_records(data, index=index)
'''
判断重复项:
- duplicated():默认判断一行数据是否与其他行有重复
- duplicated(subset='sex'):判断某字段(某列)中是否有重复,默认情况下 keep='first',也就是第一个不视为重复,之后视为重复。
- duplicated(subset='sex', keep='last'):若 keep='last',则最后一个视为不重复,之前的视为重复。
- duplicated(subset='sex', keep=False):不管是否是第一个或者最后一个,只要其他地方有出现都视为重复。
'''
'''
name
D False
B False
C False
A False
dtype: bool
'''
df.duplicated()
'''
name
D False
B False
C True
A True
dtype: bool
'''
df.duplicated(subset='sex')
'''
name
D True
B True
C False
A False
dtype: bool
'''
df.duplicated(subset='sex', keep='last')
'''
name
D True
B True
C True
A True
dtype: bool
'''
'''
删除重复项:
- drop_duplicates(subset=['sex']):默认只保留第一个
- drop_duplicates(subset=['sex'], keep='last'):保留最后一个
- drop_duplicates(subset=['sex', 'age']):传入多个参数比较,假如多个参数都相同则视为重复项,只保留第一个
'''
'''
age city name sex
name
D 10 Beijing Tom male
B 20 Shanghai Jack female
'''
df.drop_duplicates(subset=['sex'])
'''
age city name sex
name
C 30 Guangzhou Bob female
A 40 Shandong Mary male
'''
df.drop_duplicates(subset=['sex'], keep='last')
'''
age city name sex
name
D 10 Beijing Tom male
B 20 Shanghai Jack female
C 30 Guangzhou Bob female
A 40 Shandong Mary male
'''
df.drop_duplicates(subset=['sex', 'age'])
# 抽样
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
'sex': ['male', 'female', 'female', 'male'],
}
index = pd.Index(['D', 'B', 'C', 'A'], name='name')
df = pd.DataFrame.from_records(data, index=index)
'''
抽三行
age city name sex
name
A 40 Shandong Mary male
D 10 Beijing Tom male
B 20 Shanghai Jack female
'''
df.sample(n=3)
'''
replace=True 为放回的意思,也就是说还能再抽到
age city name sex
name
A 40 Shandong Mary male
D 10 Beijing Tom male
C 30 Guangzhou Bob female
'''
df.sample(n=3, replace=True)
'''
默认 axis=0,就是按照行抽取,抽 n 行
age city name sex
name
B 20 Shanghai Jack female
A 40 Shandong Mary male
D 10 Beijing Tom male
'''
df.sample(n=3, axis=0)
'''
axis=1 表示按照列抽取,抽 n 列
sex age name
name
D male 10 Tom
B female 20 Jack
C female 30 Bob
A male 40 Mary
'''
df.sample(n=3, axis=1)
'''
frac=0.5 代表抽样比为 0.5,也就是抽一半
age city name sex
name
B 20 Shanghai Jack female
C 30 Guangzhou Bob female
'''
df.sample(frac=0.5)
# 自定义函数
有时需要自定义逻辑,那么就需要三个函数:
- map:操作 Series,对每个元素实现转换
- apply:支持 Series 和 DataFrame,操作 Series 时和 map 差别不大,操作 DataFrame 时根据 axis 来决定操作行还是列
- applymap:操作 DataFrame,类似 apply
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
'sex': ['male', 'female', 'female', 'male'],
}
index = pd.Index(['D', 'B', 'C', 'A'], name='name')
df = pd.DataFrame.from_records(data, index=index)
'''
判断是否为成年人
name
D False
B True
C True
A True
Name: age, dtype: bool
'''
df['age'].map(lambda age: True if age >= 18 else False)
'''
求每列最大值
age 40
city Shanghai
name Tom
sex male
dtype: object
'''
df.apply(lambda item: item.max(), axis=0)
'''
给每行的 age + 1
name
D 11
B 21
C 31
A 41
dtype: int64
'''
df.apply(lambda item: item.age + 1, axis=1)
# 增删改查
# 查找
查找列
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
'sex': ['male', 'female', 'female', 'male'],
}
index = pd.Index(['D', 'B', 'C', 'A'], name='name')
'''
age city name sex
name
D 10 Beijing Tom male
B 20 Shanghai Jack female
C 30 Guangzhou Bob female
A 40 Shandong Mary male
'''
df = pd.DataFrame.from_records(data, index=index)
'''
按照列名查找
'''
df['age']
df.age
# age 没有值会给一个默认值 12
df.get('age', 12)
# 这个方式也是只返回一个 age 列。第一个参数代表是行,也就是所有行,age 列。
df.loc[:, 'age']
# 按照列名查找多列
df[['age', 'sex']]
# 返回 age 和 sex 列
df.loc[:, ['age', 'sex']]
'''
按序列号查找
'''
# 只返回 sex 列
df.iloc[:, 3]
# 返回 age 和 sex 列
df.iloc[:, [0, 3]]
'''
按数据类型查找
'''
df.select_dtypes(include='int64')
查找行
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
'sex': ['male', 'female', 'female', 'male'],
}
index = pd.Index(['D', 'B', 'C', 'A'], name='name')
'''
age city name sex
name
D 10 Beijing Tom male
B 20 Shanghai Jack female
C 30 Guangzhou Bob female
A 40 Shandong Mary male
'''
df = pd.DataFrame.from_records(data, index=index)
'''
按照行名查找
'''
# 这里就是返回 A 行,默认取所有列
df.loc['A']
df.loc[['A', 'B']]
'''
按照行号查找
'''
df.iloc[0]
df.iloc[[0, 1]]
# 切片获取前两行
df.iloc[0:2]
'''
条件查找
'''
df[df.age > 20]
查找行列
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
'sex': ['male', 'female', 'female', 'male'],
}
index = pd.Index(['D', 'B', 'C', 'A'], name='name')
'''
age city name sex
name
D 10 Beijing Tom male
B 20 Shanghai Jack female
C 30 Guangzhou Bob female
A 40 Shandong Mary male
'''
df = pd.DataFrame.from_records(data, index=index)
# A 行 age 列,其余和行列都一样
df.loc['A', 'age']
遍历行列
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
}
df = pd.DataFrame(data)
'''
遍历列
'''
for col in df:
# 遍历列
col
# 取值此列的所有行
df[col]
# 遍历单列
[index for index in df['age']]
'''
遍历行
'''
for index, row in df.iterrows():
f"{index}-{row['name']}-{row['age']}"
for index in df.index:
f"{index}-{df.loc[index]['age']}-{df.loc[index]['city']}"
for row in df.values:
f"{row[0]}-{row[1]}-{2}"
def desc(row):
print(f"{row['name']}-{row['age']}")
df.apply(desc, axis=1)
# 增加
- df[new_col] = data:data 为类列表数据,添加列 new_col
- df.append(other):other 为 DataFrame、Series 或类 dict,或此类型的 list,在df末尾添加新行(Series 和 dict 为单行,DataFrame 或 list 是多行)
- df.insert(loc, column, value):在指定位置插入新列
- df.loc[index, col] = data:添加行(推荐)
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
}
df = pd.DataFrame(data)
df['sex'] = ['male', 'female', 'female', 'male']
df.insert(0, 'hobby', ['羽毛球', '棒球', '舞蹈', '看球'])
'''
hobby name age city sex box
0 羽毛球 Tom 10 Beijing male 黑
1 棒球 Jack 20 Shanghai female 白
2 舞蹈 Bob 30 Guangzhou female 蓝
3 看球 Mary 40 Shandong male 红
index-Lina 跑步 Lina 20 Beijing female 灰
'''
df.loc['index-Lina'] = ['跑步', 'Lina', 20, 'Beijing', 'female']
df.loc[:, 'box'] = ['黑', '白', '蓝', '红', '灰']
# 修改
- df.columns = columns:columns 为列表, 设置新列名
- df.index = index:index为列表, 设置新索引
- df.rename(index=None, columns=None, inplace=False):index 修改索引,columns 修改列名,inplace 是否修改原始数据
- df.loc[index, col] = value:根据行或列标签修改指定数据
- df.iloc[iindex, icol] = value:根据行位置和列位置修改指定数据
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
}
df = pd.DataFrame(data)
'''
如果加上 inplace=True 则修改原数据,或者使用 df.columns = columns、df.index = index 也是修改原数据
姓名 年龄 城市
Tom Tom 10 Beijing
Jack Jack 20 Shanghai
Bob Bob 30 Guangzhou
Mary Mary 40 Shandong
'''
columns = {'name': '姓名', 'age': '年龄', 'city': '城市'}
index = {0: 'Tom', 1: 'Jack', 2: 'Bob', 3: 'Mary'}
df = df.rename(columns=columns, index=index)
# 修改指定列数据
df['年龄'] = df['年龄'] + 1
# 修改指定行列数据
df.loc['Tom'] = ['Rock', 20, 'Qingdao']
df.iloc[0] = ['Bary', 20, 'Qingdao']
df.loc[:, '年龄'] = [17, 18, 19, 20]
'''
姓名 年龄 城市
Tom Bary 50 Qingdao
Jack Jack 18 Shanghai
Bob Bob 19 Guangzhou
Mary Mary 20 Shandong
'''
df.iloc[0, 1] = 50
# 删除
import numpy as np
import pandas as pd
data = {
'name': ['Tom', 'Jack', 'Bob', 'Mary'],
'age': [10, 20, 30, 40],
'city': ['Beijing', 'Shanghai', 'Guangzhou', 'Shandong'],
}
df = pd.DataFrame(data)
# 默认不修改原数据,加上 inspect=True 可修改原数据,也可以使用 index=[n] 删除指定行
df.drop(columns=['city'])
# 修改原数据
del df['city']