数据分析和数据可视化(第二讲)-pandas

pandas数据结构:

Series
和一维数组一样。

import pandas as pd

ser_obj = pd.Series(range(10, 20))
print(ser_obj.index)
print(ser_obj.values)

实验运行的结果:

RangeIndex(start=0, stop=10, step=1)
[10 11 12 13 14 15 16 17 18 19]
0    10
1    11
2    12
3    13
dtype: int64

# 通过list构建Series
ser_obj = pd.Series(range(10, 20))
print(type(ser_obj))




DataFrame数据类型:

# -*- coding: utf-8 -*-

import pandas as pd

import numpy as np

# 通过dict构建DataFrame
dict_data = {'A': 1.,
             'B': pd.Timestamp('20161217'),
             'C': pd.Series(1, index=list(range(4)), dtype='float32'),
             'D': np.array([3] * 4, dtype='int32'),
             'E': pd.Categorical(["Python", "Java", "C++", "C#"]),
             'F': 'ChinaHadoop'}

df_obj2 = pd.DataFrame(dict_data)
print df_obj2
print "++++++++++++++++++++++++++++++++++++"
print(df_obj2.icol(2))

代码运行的结果:



通过索引选择:

# -*- coding: utf-8 -*-

import pandas as pd
import numpy as np

df_obj = pd.DataFrame(np.random.randn(5,4), columns = ['a', 'b', 'c', 'd'])
print(df_obj.head())
print '++++++++++++++++++++++++++++++++++++'
print(df_obj.loc[0:2, 'a':'d'])

要指定好类型:


实验运行的结果:



使用函数的代码:


import numpy as np
import pandas as pd

df_obj = pd.DataFrame(np.random.randn(5, 4), columns = ['a', 'b', 'c', 'd'])
print(df_obj)
print '***********************************'
print df_obj.mean()
print '***********************************'
print df_obj.max(axis=1)

程序运行的结果:

          a         b         c         d
0  0.204254  2.634199  0.431409  1.273850
1 -0.471006  1.616832 -0.079988 -0.071020
2  0.825332  1.210095 -1.032459 -1.154600
3 -1.795636 -0.192036  2.129457 -1.324958
4 -0.575655 -0.592030  1.721074  0.631608
a   -0.362542
b    0.935412
c    0.633898
d   -0.129024
dtype: float64
***********************************
0    2.634199
1    1.616832
2    1.210095
3    2.129457
4    1.721074
dtype: float64


df4 = pd.DataFrame(np.random.randn(3, 4), 
                   index=np.random.randint(3, size=3),
                   columns=np.random.randint(4, size=4))
print(df4)

随机生成索引和列名。

          1         0         3         2
2 -0.411452 -0.229687  0.975326  1.093240
1 -0.826130 -0.275579 -0.794847 -0.014010
1  1.026999 -0.467548  0.121314 -0.294583





df1.sub(df2, fill_value = 2)

s3_filled = s3.fillna(-1)

df = pd.DataFrame(np.random.randn(5,4) - 1)
print(np.abs(df))
print(df.apply(lambda x : x.max()))
df_data.isnull()

df_data.dropna()

df_data.fillna(-100)


多索引的一些操作

# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd

ser_obj = pd.Series(np.random.randn(12),
                    index=[['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd'],
                           [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2]])
print(ser_obj)
print '*********************************'
print ser_obj[:, 2]
print "**********************************"
#交换分层顺序
print(ser_obj.swaplevel())
#交换并排序分层
print("###################################")
print ser_obj.swaplevel().sortlevel()


运行结果:

a  0   -1.426302
   1    0.832818
   2   -0.347128
b  0   -0.015447
   1   -0.656397
   2   -1.546606
c  0   -0.384454
   1   -1.382357
   2    0.949415
d  0    1.362732
   1    0.294885
   2    0.522406
dtype: float64
*********************************
a   -0.347128
b   -1.546606
c    0.949415
d    0.522406
dtype: float64
**********************************
0  a   -1.426302
1  a    0.832818
2  a   -0.347128
0  b   -0.015447
1  b   -0.656397
2  b   -1.546606
0  c   -0.384454
1  c   -1.382357
2  c    0.949415
0  d    1.362732
1  d    0.294885
2  d    0.522406
dtype: float64
###################################
0  a   -1.426302
   b   -0.015447
   c   -0.384454
   d    1.362732
1  a    0.832818
   b   -0.656397
   c   -1.382357
   d    0.294885
2  a   -0.347128
   b   -1.546606
   c    0.949415
   d    0.522406
dtype: float64


分组:

对数据进行分组,然后对每组数据进行分分组,然后对每组进行统计分析

SQL能够对数据进行过滤,分组聚合

pandas能利用groupby进行更复杂的分组运算

分组运算过程

split->apply->combine

拆分:进行分组的根据

应用:每个分组运行的计算规则

合并:把每个分组的计算结果合并起来

*GroupBy对象:DataFrameGroupBy, SeriesGroupBy

*GroupBy对象没有进行实际运算,只是包含分组的中间数据

*对GroupBy对象进行分组运算/多重fenugreek运算,如mean()

size()返回每个分组的元素个数

# -*- coding: utf-8 -*-

import pandas as pd
import numpy as np
dict_obj = {'key1' : ['a', 'b', 'a', 'b',
                      'a', 'b', 'a', 'a'],
            'key2' : ['one', 'one', 'two', 'three',
                      'two', 'two', 'one', 'three'],
            'data1': np.random.randn(8),
            'data2': np.random.randn(8)}
df_obj = pd.DataFrame(dict_obj)
print("*******************************")
print(type(df_obj.groupby('key1')))
print(type(df_obj['data1'].groupby(df_obj['key1'])))

运行的实验结果:


# -*- coding: utf-8 -*-

import pandas as pd
import numpy as np
dict_obj = {'key1' : ['a', 'b', 'a', 'b',
                      'a', 'b', 'a', 'a'],
            'key2' : ['one', 'one', 'two', 'three',
                      'two', 'two', 'one', 'three'],
            'data1': np.random.randn(8),
            'data2': np.random.randn(8)}
df_obj = pd.DataFrame(dict_obj)
print("*******************************")
print(type(df_obj.groupby('key1')))
print(type(df_obj['data1'].groupby(df_obj['key1'])))
grouped1 = df_obj.groupby('key1')
print(grouped1.mean())

grouped2 = df_obj['data1'].groupby(df_obj['key1'])
print(grouped2.mean())

其中运行的结果:



自定义分组:

# -*- coding: utf-8 -*-

import pandas as pd
import numpy as np
dict_obj = {'key1' : ['a', 'b', 'a', 'b',
                      'a', 'b', 'a', 'a'],
            'key2' : ['one', 'one', 'two', 'three',
                      'two', 'two', 'one', 'three'],
            'data1': np.random.randn(8),
            'data2': np.random.randn(8)}
df_obj = pd.DataFrame(dict_obj)
print("*******************************")
# 按自定义key分组,列表
self_def_key = [1, 1, 2, 2, 2, 1, 1, 1]
print(df_obj.groupby(self_def_key).size())


实验结果:



按多个列多层分组:

# -*- coding: utf-8 -*-

import pandas as pd
import numpy as np
dict_obj = {'key1' : ['a', 'b', 'a', 'b',
                      'a', 'b', 'a', 'a'],
            'key2' : ['one', 'one', 'two', 'three',
                      'two', 'two', 'one', 'three'],
            'data1': np.random.randn(8),
            'data2': np.random.randn(8)}
df_obj = pd.DataFrame(dict_obj)
print("*******************************")
# 按多个列多层分组
print(df_obj.groupby(['key1', 'key2']).size())



GroupBy对象的分组迭代:

# -*- coding: utf-8 -*-

import pandas as pd
import numpy as np
dict_obj = {'key1' : ['a', 'b', 'a', 'b',
                      'a', 'b', 'a', 'a'],
            'key2' : ['one', 'one', 'two', 'three',
                      'two', 'two', 'one', 'three'],
            'data1': np.random.randn(8),
            'data2': np.random.randn(8)}
df_obj = pd.DataFrame(dict_obj)
grouped1 = df_obj.groupby('key1')

print("*******************************")
# 按多个列多层分组
for group_name, group_data in grouped1:
    print(group_name)
    print(group_data)


# GroupBy对象转换list
list(grouped1)

# GroupBy对象转换dict
dict(list(grouped1))

自定义函数


实战项目:

# -*- coding: utf-8 -*-

"""
    项目名称:全球食品数据分析(World Food Facts)
    项目参考:https://www.kaggle.com/bhouwens/d/openfoodfacts/world-food-facts/how-much-sugar-do-we-eat/discussion
"""
import zipfile
import os
import pandas as pd
import matplotlib.pyplot as plt


def unzip(zip_filepath, dest_path):
    """
        解压zip文件
    """
    with zipfile.ZipFile(zip_filepath) as zf:
        zf.extractall(path=dest_path)


def get_dataset_filename(zip_filepath):
    """
            获取数据库文件名
    """
    with zipfile.ZipFile(zip_filepath) as zf:
        return zf.namelist()[0]


def run_main():
    """
        主函数
    """
    # 声明变量
    dataset_path = './data'  # 数据集路径
    zip_filename = 'open-food-facts.zip'  # zip文件名
    zip_filepath = os.path.join(dataset_path, zip_filename)  # zip文件路径
    dataset_filename = get_dataset_filename(zip_filepath)  # 数据集文件名(在zip中)
    dataset_filepath = os.path.join(dataset_path, dataset_filename)  # 数据集文件路径

    print('解压zip...', end='')
    unzip(zip_filepath, dataset_path)
    print('完成.')

    # 读取数据
    data = pd.read_csv(dataset_filepath, usecols=['countries_en', 'additives_n'])

    # 分析各国家食物中的食品添加剂种类个数
    # 1. 数据清理
    # 去除缺失数据
    data = data.dropna()    # 或者data.dropna(inplace=True)

    # 将国家名称转换为小写
    # 课后练习:经过观察发现'countries_en'中的数值不是单独的国家名称,
    # 有的是多个国家名称用逗号隔开,如 Albania,Belgium,France,Germany,Italy,Netherlands,Spain
    # 正确的统计应该是将这些值拆开成多个行记录,然后进行分组统计
    data['countries_en'] = data['countries_en'].str.lower()

    # 2. 数据分组统计
    country_additives = data['additives_n'].groupby(data['countries_en']).mean()

    # 3. 按值从大到小排序
    result = country_additives.sort_values(ascending=False)

    # 4. pandas可视化top10
    result.iloc[:10].plot.bar()
    plt.show()

    # 5. 保存处理结果
    result.to_csv('./country_additives.csv')

    # 删除解压数据,清理空间
    if os.path.exists(dataset_filepath):
        os.remove(dataset_filepath)

if __name__ == '__main__':
    run_main()



























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值