合并
merge()
# 基于列进行合并, how有多种方式 inner内联 outer外联 left 左联 right 右联
df1.merge(df2, left_on='key1', right_on='key2', how='inner')
df1.merge(df2, on='key') # 如果两个表合并的依据的列明是同名的时候 可以直接用on来代替left_on 和 right_on
df1.merge(df2, left_index=True', right_index=True, how='outer') # 基于行索引进行外联合并
df1.merge(df2, left_index=True', right_index='key') # 可以混合考虑索引和某一列来进行合并
参数:
on 用于连接的列名。必须存在于左右两个Dataframe对象中
left_on 左侧Dataframe中用作连接键的列
right_on 右侧Dataframe中用作连接键的列
left_index 将左侧的行索引引用作其连接键
right_index 将右侧的行索引引用作其连接键
contact() # 轴方向上的合并
pd.contact([df1, df2], axis=0) # 将df1, df2两个数据表在axis=0的方向进行合并
In [61]: s1 = Series([0, 1], index=['a', 'b'])
In [62]: s2 = Series([2, 3, 4], index=['c', 'd', 'e'])
In [63]: s3 = Series([5, 6], index=['f', 'g'])
对这些对象调⽤concat可以将值和索引粘合在⼀起:
In [64]: pd.concat([s1, s2, s3])
Out[64]:
a 0
b 1
c 2
d 3
e 4
f 5
g 6
参数:
objs 参与连接的pandas对象的列表或字典。唯一必须的参数
axis 指明连接的轴向,默认为0
combine_first ()打补丁
df1.combine_first(df2) # 如果df1中某些位置的数据是缺失的, 可以用df2中对应位置的值俩填补
移除重复值
DataFrame的duplicated⽅法返回⼀个布尔型Series, 表⽰各⾏是否是重
复⾏:
In [128]: data.duplicated()
Out[128]:
0 False
1 True
2 False
3 False
4 True
5 False
6 True
还有⼀个与此相关的drop_duplicates⽅法, 它⽤于返回⼀个移除了重复⾏的Data-Frame:
In [129]: data.drop_duplicates()
Out[129]:
k1 k2
0 one 1
2 one 2
3 two 3
5 two 4
数据转换
Series的map⽅法可以接受⼀个函数或含有映射关系的字典型对象, 但是这⾥有⼀个⼩问题,
即有些⾁类的⾸字母⼤写了, ⽽另⼀些则没有。 因此, 我们还需要将各个值转换为⼩写:
In [136]: data['animal'] = data['food'].map(str.lower).map(meat_to_animal)
数据替换
如果你希望⼀次性替换多个值, 可以传⼊⼀个由待替换值组成的列表
以及⼀个替换值:
In [142]: data.replace([-999, -1000], np.nan)
Out[142]:
0 1
1 NaN
2 2
3 NaN
4 NaN
5 3
如果希望对不同的值进⾏不同的替换, 则传⼊⼀个由替换关系组成的
列表即可:
In [143]: data.replace([-999, -1000], [np.nan, 0])
Out[143]:
0 1
1 NaN
2 2
3 NaN
4 0
5 3
传⼊的参数也可以是字典:
In [144]: data.replace({-999: np.nan, -1000: 0})
Out[144]:
0 1
1 NaN
2 2
3 NaN
4 0
5 3
重命名轴索引
In [145]: data = DataFrame(np.arange(12).reshape((3, 4)),
...: index=['Ohio', 'Colorado', 'New York'],
...: columns=['one', 'two', 'three', 'four'])
跟Series⼀样, 轴标签也有⼀个map⽅法:
In [146]: data.index.map(str.upper)
Out[146]: array([OHIO, COLORADO, NEW YORK], dtype=object)
你可以将其赋值给index, 这样就可以对DataFrame进⾏就地修改了:
In [147]: data.index = data.index.map(str.upper)
In [148]: data
Out[148]:
one two three four
OHIO 0 1 2 3
COLORADO 4 5 6 7
NEW YORK 8 9 10 11
如果想要创建数据集的转换版( ⽽不是修改原始数据) , ⽐较实⽤的
⽅法是rename:
In [149]: data.rename(index=str.title, columns=str.upper)
Out[149]:
ONE TWO THREE FOUR
Ohio 0 1 2 3
Colorado 4 5 6 7
New York 8 9 10 11
In [150]: data.rename(index={'OHIO': 'INDIANA'},
...: columns={'three': 'peekaboo'})
离散化
In [153]: ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
接下来将这些数据划分为“18到25”、 “26到35”、 “35到60”以及“60以
上”⼏个⾯元。 要实现该功能, 你需要使⽤pandas的cut函数:
In [154]: bins = [18, 25, 35, 60, 100]
In [155]: cats = pd.cut(ages, bins)
In [156]: cats
Out[156]:
Categorical:
array([(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], (18, 25],
(35, 60], (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]], dtype=ob
Levels (4): Index([(18, 25], (25, 35], (35, 60], (60, 100]], dtype=
假设你想要找出某列中绝对值⼤⼩超过3的值:
In [173]: col = data[3]
In [174]: col[np.abs(col) > 3]
要选出全部含有“超过3或- 3的值”的⾏, 你可以利⽤布尔型DataFrame
以及any⽅法:
In [175]: data[(np.abs(data) > 3).any(1)]
根据这些条件, 即可轻松地对值进⾏设置。 下⾯的代码可以将值限制
在区间- 3到3以内:
In [176]: data[np.abs(data) > 3] = np.sign(data) * 3
字符串的处理
只有Series对象有字符串处理方法
series.str.upper()/series.str.lower()/series.str.title()# 大写、小写、第一个字母大写
series.str.strip() # 去除字符串两边的\r\n\t
series.str.split('cond') #拆分,cond值拆分条件
series.str.join('cond') # 合并, 将列表里面的元素进行合并
series.str.replace() # 替换
series.str.contains('cond') # 判断是否包含'cond',如果包含则对应位置返回true
series.str.slice(start,stop,step)# 切片
series.str.startswith(exam)#判断以exam开始
series.str.endswith(exam)#判断以exam结尾
分组
In [13]: df = DataFrame({'key1' : ['a', 'a', 'b', 'b', 'a'],
...: 'key2' : ['one', 'two', 'one', 'two', 'one'],
...: 'data1' : np.random.randn(5),
...: 'data2' : np.random.randn(5)})
In [14]: df
Out[14]:
data1 data2 key1 key2
0 -0.204708 1.393406 a one
1 0.478943 0.092908 a two
2 -0.519439 0.281746 b one
3 -0.555730 0.769023 b two
4 1.965781 1.246435 a one
假设你想要按key1进⾏分组, 并计算data1列的平均值。 实现该功能的
⽅式有很多, ⽽我们这⾥要⽤的是: 访问data1, 并根据key1调⽤groupby:
In [15]: grouped = df['data1'].groupby(df['key1'])
数据( Series) 根据分组键进⾏了聚合, 产⽣了⼀个新的Series, 其索引为key1
列中的唯⼀值。 之所以结果中索引的名称为key1, 是因为原始DataFrame的
列df['key1']就叫这个名字。
如果我们⼀次传⼊多个数组, 就会得到不同的结果:
In [18]: means = df['data1'].groupby([df['key1'], df['key2']]).mean()
In [19]: means
Out[19]:
key1 key2
a one 0.880536
two 0.478943
b one -0.519439
two -0.555730
计算data1的平均值但是按照key1,key2分组
⽆论你准备拿groupby做什么, 都有可能会⽤到GroupBy的size⽅法,
它可以返回⼀个含有分组⼤⼩的Series:
In [26]: df.groupby(['key1', 'key2']).size()
Out[26]:
key1 key2
a one 2
two 1
b one 1
two 1
groupby默认是在axis=0上进⾏分组的, 通过设置也可以在其他任何轴上进⾏分组
对于由DataFrame产⽣的GroupBy对象, 如果⽤⼀个( 单个字符串) 或
⼀组( 字符串数组) 列名对其进⾏索引, 就能实现选取部分列进⾏聚合的
⽬的。 也就是说:
df.groupby('key1')['data1']
df.groupby('key1')[['data2']]
是以下代码的语法糖:
df['data1'].groupby(df['key1'])
还可以以列表的形式来分组
df[['data2']].groupby(df['key1'])
如果只需计算data2列的平均值并以DataFrame形式得到结
果, 我们可以编写:
In [34]: df.groupby(['key1', 'key2'])[['data2']].mean()
经过优化的groupby的方法
count 分组中非NA的值
sum 非NA值得和
mean 非NA值得平均值
median 非NA值得算术中位数
std、var 无偏(分母为n-1)标准差和方差
min/max 非NA值得最小值和最大值
prod 非NA值得积
first/last 第一个和最后一个非NA值
生成新的一列
# 添加“⼩费占总额百分⽐”的列
In [61]: tips['tip_pct'] = tips['tip'] / tips['total_bill']
数据分析--数据规整化--数据处理
最新推荐文章于 2022-07-21 10:38:08 发布