原创

机器学习手册02---数据整理的起点【分组】


分组”是数据整理经常进行的操作,它才是数据整理的起点。我们经常在处理大量数据的时候,想按照某种联系或某种特殊的关系来关联表中的一部分数据,进行统计分析,那么分组无疑是最高效的处理手段。

1.根据值对行分组

根据一些共有的值对行分组,groupby是pandas中最强大的功能之一。

import pandas as pd

# 载入准备好的泰坦尼克号数据集
dataframe = pd.read_csv('train.csv')

# 根据Sex列的值来进行分组,并计算每一组的平均值
print(dataframe.groupby('Sex').mean())

# 根据Survived列的值进行分组,进而通过Name来计算每组的个数
print(dataframe.groupby('Survived')['Name'].count())

# 根据Sex与Survived列的值进行分组,进而通过Age来计算每组的平均值
print(dataframe.groupby(['Sex', 'Survived'])['Age'].mean())
Sex      PassengerId  Survived   Pclass       Age
female   431.028662  0.742038  2.159236  27.915709
male     454.147314  0.188908  2.389948  30.726645

Survived
0         549
1         342
Name: Name, dtype: int64

Sex      Survived
female   0           25.046875
         1           28.847716
male     0           31.618056
         1           27.276022
Name: Age, dtype: float64

【小提示】:初学者可能会写出下面这之一类代码:dataframe.groupby('Sex'),但是输出结果可能根本看不懂是什么意思。原因:groupby需要和一些作用与组(group)的操作配合使用(例如:平均值、中位数、总和等等)。

# 奇怪的输出结果
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x0000019FD8DE7F28>

2.根据时间段对行分组

resample():按时间段对行分组。

import pandas as pd
import numpy as np

# 创建日期范围,date_range()时间序列:起始日期06/06/2017,间隔30S,生成100000个
time_index = pd.date_range('06/06/2017', periods=100000, freq='30S')

# 创建数据帧,且index为日期
dataframe = pd.DataFrame(index=time_index)

# 创建一列随机变量:1~9共10个数,随机生成100000个
dataframe['Sale_Amount'] = np.random.randint(1, 10, 100000)

# 查看前4行
print(dataframe.head(4))

# 按周W进行分组,计算每一周的总和
print(dataframe.resample('W').sum())

# 按两周2W进行分组,计算每两周的平均值
print(dataframe.resample('2W').mean())

# 按每月M进行分组,计算每月的行数
print(dataframe.resample('M').count())
                     Sale_Amount
2017-06-06 00:00:00            3
2017-06-06 00:00:30            7
2017-06-06 00:01:00            7
2017-06-06 00:01:30            4

            Sale_Amount
2017-06-11        86264
2017-06-18       101552
2017-06-25       101267
2017-07-02       100818
2017-07-09       100173
2017-07-16        10300

            Sale_Amount
2017-06-11     5.000868
2017-06-25     4.989931
2017-07-09     4.996255
2017-07-23     5.038942

            Sale_Amount
2017-06-30        72000
2017-07-31        28000

3.遍历一个列的数据

将pandas的列视为与Python中的其他序列一样:

import pandas as pd

# 载入准备好的泰坦尼克号数据集
dataframe = pd.read_csv('train.csv')

# 方法一:for循环,打印前两行中的名字的大写
for name in dataframe['Name'][0:2]:
    print(name.upper())

# 方法二:列表解析
print([name.upper() for name in dataframe['Name'][0:2]])
BRAUND, MR. OWEN HARRIS
CUMINGS, MRS. JOHN BRADLEY

['BRAUND, MR. OWEN HARRIS', 'CUMINGS, MRS. JOHN BRADLEY']

【说明】:遍历一个列中的所有元素,并作某个操作有3个常见的方法:(1)for循环(2)列表解析(3)pandas的apply方法

4.对一列所有元素应用某个函数

apply对一列的所有元素应用一个内置的或者自定义的函数:

import pandas as pd

# 载入准备好的泰坦尼克号数据集
dataframe = pd.read_csv('train.csv')

# 方法三:创建一个函数:大写
def uppercase(x):
    return x.upper()

# 应用函数,查看前两行
print(dataframe['Name'].apply(uppercase)[0:2])
0       BRAUND, MR. OWEN HARRIS
1    CUMINGS, MRS. JOHN BRADLEY
Name: Name, dtype: object

4.对所有分组应用某个函数

groupby与apply联合使用:

import pandas as pd

dataframe = pd.read_csv('train.csv')

print(dataframe.groupby('Sex').count())

# 对行分组,然后在每一组上应用函数
print(dataframe.groupby('Sex').apply(lambda x: x.count()*100))
Sex     PassengerId  Survived  Pclass  Name  Age
female          314       314     314   314  261
male            577       577     577   577  453

Sex     PassengerId  Survived  Pclass   Name    Sex    Age
female        31400     31400   31400  31400  31400  26100
male          57700     57700   57700  57700  57700  45300

5.连接多个数据帧

concat方法:参数axis=0,延着行方向连接数据。

import pandas as pd

# 注意:columns=['id', 'first', 'last']是为了保证数据帧打印出来的顺序
# 创建数据帧
data_a = {'id': ['1', '2', '3'],
          'first': ['Alex', 'Amy', 'Allen'],
          'last': ['Anderson', 'Ackerman', 'Ali']}
dataframe_a = pd.DataFrame(data_a, columns=['id', 'first', 'last'])

# 创建数据帧
data_b = {'id': ['4', '5', '6'],
          'first': ['Bill', 'Brian', 'Bran'],
          'last': ['Bonder', 'Black', 'Balwner']}
dataframe_b = pd.DataFrame(data_b, columns=['id', 'first', 'last'])

# 沿着行和列连接两个数据帧
print(pd.concat([dataframe_a, dataframe_b], axis=0))
print(pd.concat([dataframe_a, dataframe_b], axis=1))
  id  first      last
0  1   Alex  Anderson
1  2    Amy  Ackerman
2  3  Allen       Ali
0  4   Bill    Bonder
1  5  Brian     Black
2  6   Bran   Balwner

  id  first      last id  first     last
0  1   Alex  Anderson  4   Bill   Bonder
1  2    Amy  Ackerman  5  Brian    Black
2  3  Allen       Ali  6   Bran  Balwner

可能说到连接,你还会想到另一种常见的方法,在之前的一篇文章中已经用过1次:

# 创建新的一行
row_new = pd.Series([10, 'Chris', 'Chillon'], index=['id', 'first', 'last'])

# append():增加一行
print(dataframe_a.append(row_new, ignore_index=True))
   id  first      last
0   1   Alex  Anderson
1   2    Amy  Ackerman
2   3  Allen       Ali
3  10  Chris   Chillon

6.合并数据帧

merger(): 巧用on参数来设置合并的类型

import pandas as pd

# 创建数据帧
employee_data = {'id': ['1', '2', '3', '4'],
                 'name': ['Amy', 'Allen', 'Alice', 'Tim']}
dataframe_employees = pd.DataFrame(employee_data, columns=['id', 'name'])

# 创建数据帧
sales_data = {'id': ['3', '4', '5', '6'],
              'total_sales': [23456, 2512, 2345, 1455]}
dataframe_sales = pd.DataFrame(sales_data, columns=['id', 'total_sales'])

print(dataframe_employees)
print(dataframe_sales)
  id   name
0  1    Amy
1  2  Allen
2  3  Alice
3  4    Tim

  id  total_sales
0  3        23456
1  4         2512
2  5         2345
3  6         1455
# 合并数据帧,默认等值连接
print(pd.merge(dataframe_employees, dataframe_sales, on='id'))

# how='outer'是外连接(outer join)
print(pd.merge(dataframe_employees, dataframe_sales, on='id', how='outer'))

# how='left'是左连接
print(pd.merge(dataframe_employees, dataframe_sales, on='id', how='left'))

# 根据id合并共有的部分
print(pd.merge(dataframe_employees, dataframe_sales, left_on='id', right_on='id'))
  id   name  total_sales
0  3  Alice        23456
1  4    Tim         2512

  id   name  total_sales
0  1    Amy          NaN
1  2  Allen          NaN
2  3  Alice      23456.0
3  4    Tim       2512.0
4  5    NaN       2345.0
5  6    NaN       1455.0

  id   name  total_sales
0  1    Amy          NaN
1  2  Allen          NaN
2  3  Alice      23456.0
3  4    Tim       2512.0

  id   name  total_sales
0  3  Alice        23456
1  4    Tim         2512

【小提示】:其实上述几个合并过程类似于,数据库SQL的查询语句

Python
机器学习
  • 作者:李延松(联系作者)
  • 发表时间:2020-07-19 18:22
  • 版本声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 公众号转载:请在文末添加作者公众号二维码

评论

留言