Pandas数据操作归纳总结

Pandas建立在NumPy之上,旨在与许多其他第三方库完美地集成在科学计算环境中。它的两个主要数据结构是Series(1维)和DataFrame(2维)。

一、Pandas数据结构:一维数组(Series)

1、创建Series数组

Series是一个一维的数据类型,其中每一个元素都有一个标签。类似于Numpy中元素带标签的数组。其中,标签可以是数字或者字符串。

import numpy as np
import pandas as pd  

# 直接创建
a = pd.Series([1, 2, 5, 6, 8])  
print(a)

# 用标量创建
b = pd.Series(5, index = [0,1,2,3])
print(b)

# 从numpy数组创建
data1 = np.array(['a','b', 3, 4])
c = pd.Series(data1, index = ['a','b','c','d'])
print(c)

# 从字典创建
data2 = {'a':1, 'b':2, 'c':3}
d = pd.Series(data2, index = ['a','b','c','d'])
print(d)

2、Series数组的索引

Series对象提供了几种不同的索引方法。

(1)枚举索引

枚举索引按照index值进行索引。
index值默认使用下标,下标总是从0开始的,而且索引值总是数字。也可以用关键字为index赋值,关键字既可以是数字,也可以是字符串等。

import numpy as np
import pandas as pd  

# 使用下标作为index(默认)
a = pd.Series([1, 2, 5, 6, 8])  
print(a.index)
print(a.values)  # [1 2 5 6 8]
print(a[4])  # 8
print(a[[1,3]].values)   # [2, 6]

# 使用关键字作为index
b = pd.Series([1, 2, 5, 6, 8], index = [1, 2, 'k', 'j', 'k']) 
print(b.index)
print(b.values)  # [1 2 5 6 8]
print(b[4])  #  优先查找关键字如果没有匹配的关键字则按照下标查
print(b[[2,'j']].values)   # [2, 6]
print(b[[2,'k']].values)   # [2 5 8]
(2)布尔索引
import numpy as np
import pandas as pd  

# 使用布尔索引
a = pd.Series([1, 2, 5, 6, 8], index=['a', 'b', 'c', 'd', 'd'])  
print(a.index)
print(a.values)  # [1 2 5 6 8]
print(a>3)  # False False True True True
print(a[a>3].values)   # [5 6 8]
(3)切片索引

切片索引使用的是下标,不会受到index的影响

import numpy as np
import pandas as pd  

a = pd.Series([1, 2, 5, 6, 8])  
print(a[1:3].values)   # [2 5]

b = pd.Series([1, 2, 5, 6, 8], index = [1, 2, 3, 4, 5]) 
print(b[1:3].values)   # [2 5]

二、Pandas数据结构:数据表(Dataframe)

Pandas提供了一种名为Dataframe的二维表结构。可以把DataFrame想象成一个电子表格,它由行名(index)、列名(columns)和数据(values)组成。

1、创建Dataframe数据表

(1)从字典创建
import numpy as np
import pandas as pd

data = {
    "a":[1,2,3],
    "b":[4,5,6],
    "c":[7,8,9]   
}

# 使用默认的下标作为行(index)
df1 = pd.DataFrame(data)
print(df1)

# 使用提供的关键字作为行(index)
df2 = pd.DataFrame(data, index=['A','B','C'])
print(df2)
(2)从Series创建
import numpy as np
import pandas as pd

data = {"a":pd.Series([1,2,3],['A','B','C']),
        "b":pd.Series([4,5,6],['A','B','C']),
        "c":pd.Series([7,8,9],['A','B','C'])}

df = pd.DataFrame(data)
print(df)
(3)从二维数组直接创建

由二维数组直接创建DataFrame,得到一样形状的结果数据,如果不指定index和columns,两者均返回默认数字格式

import numpy as np
import pandas as pd

data = np.random.rand(9).reshape(3,3)

df = pd.DataFrame(data, index = ['a', 'b', 'c'], columns = ['one','two','three'])
print(df)

2、Dataframe数据表的索引

(1)枚举索引
import numpy as np
import pandas as pd

data = {
    "a":[1,2,3],
    "b":[4,5,6],
    "c":[7,8,9]   
}

df = pd.DataFrame(data, index=['x','y','z'])
print(df)

# 访问某列的某个元素
print(df['a'][0])
print(df['a']['x'])

# 访问某行的某个元素
print(df.T['x'][0])
print(df.T['x']['b'])

# 访问某列的某几个元素
print(df['a'][['x','y','z']].values)
print(df['a'][[0,1,2]].values)
(2)布尔索引
import numpy as np
import pandas as pd

data = {
    "a":[1,2,3],
    "b":[4,5,6],
    "c":[7,8,9]   
}

df = pd.DataFrame(data, index=['x','y','z'])
print(df)

# 单个列的布尔索引
print(df['b']>3)
print(df['b'][df['b']>3])
print(df['b'][df['b']>3].values)

# 整个表的布尔索引
print(df>3)
print(df[df>3])
print(df[df>3].values)
(3)切片索引
import numpy as np
import pandas as pd

data = {
    "a":[1,2,3],
    "b":[4,5,6],
    "c":[7,8,9]   
}

df = pd.DataFrame(data, index=['x','y','z'])
print(df)

# 单个列的切片索引
print(df['b'][0:2])

# 整个表的切片索引
print(df[0:1][0:2])
(4)loc和iloc索引
import numpy as np
import pandas as pd

data = {
    "a":[1,2,3],
    "b":[4,5,6],
    "c":[7,8,9]   
}

df1 = pd.DataFrame(data)
df2 = pd.DataFrame(data, index=['x','y','z'])

# loc索引
print(df1.loc[1, 'a'])
print(df1.loc[[0,1,2], 'a'])
print(df1.loc[0:2, 'a'])
print(df2.loc['y', 'a'])
print(df2.loc[['x','y','z'], 'a'])

# iloc索引
print(df1.iloc[1, 0])
print(df1.iloc[[0,1,2], 0])
print(df1.iloc[0:3, 0])
print(df2.iloc[1, 0])
print(df2.iloc[[0,1,2], 0])

3、多索引Dataframe数据表

# 创建多索引
midx = pd.MultiIndex(levels=[['Tom', 'Bob', 'Jam'], ['income', 'weight', 'length']],
                     codes=[[0, 0, 0, 1, 1, 1, 2, 2, 2],[0, 1, 2, 0, 1, 2, 0, 1, 2]])
df = pd.DataFrame(index=midx, 
                  columns=['max', 'min'],
                  data=[[200, 100],[55, 50], [1.5, 1.4],  # Tom收入,体重,身高
                        [400, 300],[65, 60], [1.6, 1.5],  # Bob收入,体重,身高
                        [600, 500],[75, 70], [1.8, 1.7]]) # Jam收入,体重,身高
print(df)

三、Pandas数据 I/O

import numpy as np
import pandas as pd

data = {
    "a":[1,2,3],
    "b":[4,5,6],
    "c":[7,8,9]   
}

df = pd.DataFrame(data)

# 保存和读取csv格式
df.to_csv('01.csv', index=False, encoding='utf-8')
df1 = pd.read_csv('01.csv')
print(df1)

# 保存和读取execl格式,需安装xlrd和openpyxl
df.to_excel('02.xlsx', index=False, encoding='utf-8')
df2 = pd.read_excel('02.xlsx')
print(df2)

# 保存和读取txt格式
df.to_csv('03.txt', sep='@', index=False, encoding='utf-8')
df3 = pd.read_csv('03.txt', sep='@')
print(df3)

# 保存和读取pickling格式
df.to_pickle('04.pkl')
df4 = pd.read_pickle('04.pkl')
print(df4)

了解更多

四、Series和DataFrame的基本操作

1、Series和DataFrame添加删除元素

(1)Series添加删除元素
import numpy as np
import pandas as pd

s1 = pd.Series([-1, -2, -3], index=['a', 'b', 'c'])
s2 = pd.Series([1, 2, 3, 4], index=['e', 'f', 'c', 'd'])

# 插入元素
s1['d'] = -4
s3 = s1.append(pd.Series([-4], index=['a'])) # verify_integrity=True 标签重复报错 
print(s3)
s4 = s1.append(s2)
print(s4)

# 删除元素
s1.drop('d', inplace=False)  # 设置为True时修改原Series
print(s1)
s1.pop('d')
print(s1)
(1)DataFrame添加删除元素
import numpy as np
import pandas as pd

df = pd.DataFrame({'one' : pd.Series([-1, -2, -3]),
                   'two' : pd.Series([1, 2, 3, 4])})

# 添加新列
df['three'] = pd.Series([10,20,30])
df['four'] = df['one']+df['three']
df.loc[:, "five"] = [1, 4, 5, 9]
print(df)

# 添加新行
temp_df = pd.DataFrame([[5, 6], [7, 8]], columns=['one','two'])
df = df.append(temp_df, sort=False, ignore_index=True)  # ignore_index=True用于重新生成索引
print(df)
df.loc[df.shape[0]] = [0, 0, 0, 0, 0]
print(df)

# 删除行
df.drop(3, axis=0, inplace=True)
print(df)

# 删除列
df.drop(['four','five'], axis=1, inplace=True)
print(df)

2、Series和DataFrame数据排重

import numpy as np
import pandas as pd

s = pd.Series([-1, -1, -2, -2, -3])
df = pd.DataFrame({'k1':['one','two']*3+['two'],
                   'k2':[1,1,1,2,1,3,3]})

# 查看是否重复
print(s.duplicated())
print(df.duplicated())
# 删除所有重复
print(s.drop_duplicates())
print(df.drop_duplicates())
# 删除某列的重复值
print(df.drop_duplicates(['k1']))

3、Series和DataFrame数据替换和映射

(1)数据替换
import numpy as np
import pandas as pd

s = pd.Series([-1, -1, -2, -2, -3])
df = pd.DataFrame({'k1':['one','two']*3+['two'],
                   'k2':[1,1,1,2,1,3,3]})

# Series数据替换
print(s.replace(-3, 999))
print(s.replace([-1,-2], 3))
print(s.replace({-1:'a',-2:'b'}))

# DataFrame数据替换
print(df.replace(1, 999))
print(df.replace([1,2], 3))
print(df.replace({1:'a',2:'b'}))
(2)数据映射

map()函数就是一个数据到一个数据的映射关系,中间没有对数据的增删改
map(function,list)就是将list里面的数据取出来然后用于function

import numpy as np
import pandas as pd


df = pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon',
                            'Pastrami', 'corned beef', 'Bacon',
                            'pastrami', 'honey ham', 'nova lox'],
                   'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})

meat_to_animal = {
    'bacon': 'pig',
    'pulled pork': 'pig',
    'pastrami': 'cow',
    'corned beef': 'cow',
    'honey ham': 'pig',
    'nova lox': 'salmon'
}

###################### 方法一 ########################

# 字符串数据才有lower()
lowercased = df['food'].str.lower()
print(lowercased)

# 数据映射
print(lowercased.map(meat_to_animal))
df['animal1']=lowercased.map(meat_to_animal)
print(df)

###################### 方法二 ########################

# df['animal2']=df['food'].map(lambda x : meat_to_animal[x.lower()])
transform = lambda x : meat_to_animal[x.lower()]
df['animal2']=df['food'].map(transform)
print(df)

4、DataFrame行列变换

(1)使用 numpy 实现转置
import numpy as np
import pandas as pd

df = pd.DataFrame([[0, 1, 2], 
                   [3, 4, 5]],  columns=['c1', 'c2', 'c3'])
print(df)

df2 = pd.DataFrame(df.values.T, index=df.columns, columns=df.index)
print(df2)
(2)利用 pandas 多级索引实现转置

stack() 会将数据的列"旋转"为行,新的行索引比原来的行索引低了一个级别(0的级别最高)。
unstack() 将数据的行"旋转"为列,默认旋转的是级别最低的索引。

import numpy as np
import pandas as pd

df = pd.DataFrame([[0, 1, 2], 
                   [3, 4, 5]],  columns=['c1', 'c2', 'c3'])
print(df)

# 列索引转为行索引
df = df.stack()
print(df)

# 最高级的行索引转为列索引
df = df.unstack(0)
print(df)

# 一步完成转换
print(df.stack().unstack(0))

5、DataFrame合并与拆分

(1)堆叠

concat()能够实现轴向数据集的堆叠

import numpy as np
import pandas as pd

s1 = pd.Series([0, 1])
s2 = pd.Series([2, 3, 4])
s3 = pd.Series([5, 6])

# 纵向堆叠
df1 = pd.concat([s1, s2, s3], ignore_index=True)  # 默认axis=0
print(df1)
df2 = pd.concat([s1, s2, s3])
df2.set_axis(range(len(df2)), inplace=True)
print(df2)

# 横向堆叠
df3 = pd.concat([s1, s2, s3], axis=1)
print(df3)
(2)连接

merge()可根据一个或者多个键将不同的DataFrame连接在一起,类似于SQL数据库中的join操作

import numpy as np
import pandas as pd

df1 = pd.DataFrame({'userid': [1,2,3,4], 'level': list('ssab')})
df2 = pd.DataFrame({'userid': [1,3,5], 'age': [16, 22, 34]})

print(pd.merge(df1, df2))  # 默认使用交集(how='inner')作为合并方式
print(pd.merge(df1, df2, how='outer'))   # 使用并集作为合并方式

print(pd.merge(df1, df2, how='left'))  # 左合并
print(pd.merge(df1, df2, how='right'))  # 右合并

print(pd.merge(df1, df2, on=['userid']))  # 指定连接列
(3)拆分
import numpy as np
import pandas as pd

df = pd.DataFrame([['Computer', 'Mac-Dell'], 
                   ['Computer', 'Mac-XiaoMi'],
                   ['Computer', 'Mac-HuaWei-9X']],  columns=['Type', 'Brands_rank'])

print(df)

# 一列拆多列
df['Brands-Second'] = df.Brands_rank.apply(lambda x: x.split('-')[1])
df['Brands-Third'] = df.Brands_rank.apply(lambda x: x.split('-')[2] if x.count('-') >= 2 else np.nan)
print(df)

# 一行拆多行
df2 = df
df2 = df.Brands_rank.str.split('-', expand=True).stack().to_frame() 
df2 = df2.reset_index(level=1, drop=True).rename(columns={0:'Brands'})
print(df[['Type']].join(df2))

6、DataFrame排序

import numpy as np
import pandas as pd

df = pd.DataFrame([[0, 1, 2], 
                   [3, 4, 5]],  columns=['c1', 'c2', 'c3'])

############ 列索引排序 #############

# 按行索引升序排序
print(df.sort_index())
# 按行索引降序排序
print(df.sort_index(ascending=False))

############ 行索引排序 #############
# 按列索引升序排序
print(df.sort_index(axis=1))
# 按列索引降序排序
print(df.sort_index(axis=1, ascending=False))

############ 值排序 #################
# 按某列的值升序排序
print(df.sort_values(by='c2'))
# 按某列的值降序排序
print(df.sort_values(by='c2', ascending=False))
# 多列值降序排序
print(df.sort_values(by=['c2', 'c3'], ascending=False))

更多

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容