pandas中DataFrame各种方法总结(持续更新)

pandas 最有趣的地方在于里面隐藏了很多包。它是一个核心包,里面有很多其他包的功能。这点很棒,因为你只需要使用 pandas 就可以完成工作。pandas 相当于 python 中 excel:它使用表(也就是 dataframe),能在数据上做各种变换,但还有其他很多功能。

文章目录

DataFrame的创建

操作代码实现返回值说明通过ndarray构建DataFramepd.DataFrame(array)

pd.DataFrame(np.random.randn(3,4), columns = [‘a’, ‘b’, ‘c’])新DataFrame通过Numpy的ndarray构建,

自动生成行列索引,

columns 可指定列索引名通过dict构建DataFramepd.DataFrame(dict)

dict = {‘A’: 1,

‘B’: pd.Timestamp(‘20190616’),

‘C’:pd.Series(1,index=list(range(4)),dtype=’float32′),

‘D’: np.array([3] * 4,dtype=’int32′),

‘E’: [“Python”,”Java”,”C++”,”C”],

‘F’: ‘tiger’ }新DataFramedict的key为列标签

value为元素

自动生成行索引

DataFrame的相关操作

DataFrame的基本属性和方法

读数据

常用读取文件函数 read_csv, read_excel,read_clipboard, read_sql
如:data = pd.read_csv( my_file.csv , sep= ; , encoding= latin-1 , nrows=1000, skiprows=[2,5])
注:sep 代表的是分隔符。如果你在使用法语数据,excel 中 csv 分隔符是「;」,因此你需要显式地指定它。编码设置为 latin-1 来读取法语字符。nrows=1000 表示读取前 1000 行数据。skiprows=[2,5] 表示你在读取文件的时候会移除第 2 行和第 5 行。

写数据

data.to_csv( my_new_file.csv , index=None)
注:index=None 表示将会以数据本来的样子写入。如果没有写 index=None,你会多出一个第一列,内容是 1,2,3,…,一直到最后一行。
其他的写入函数.to_excel, .to_json, .to_pickle

检查数据

Gives (#rows, #columns) 给出行数和列数
data.describe() 计算基本的统计数据

查看数据

从头查看数据 head()

data.head() 默认返回5行 返回值为DataFrame
head( n ) 方法用于读取前面的 n 行,如果不填参数 n ,默认返回 5 行

从尾查看数据 tail ( )

data.tail() 默认返回5行 返回值为DataFrame
tail( n ) 方法用于读取尾部的 n 行,如果不填参数 n ,默认返回 5 行,空行各个字段的值返回 NaN。

数据形状 shape

data.shape 获取数据形状 返回值为元组
假设data为10行8列的数据 则返回(10,8)
扩展:在机器学习与深度学习模型中,需要将数据集划分为训练集和测试集会造成索引的混乱
可以通过shape方法让索引重新有序
如: data.index = range(data.shape[0])
也可以使用data.reset_index(drop=True)

转置 T

data.T 进行数据转置 返回值为DataFrame 不改变原来的DataFrame
假设data为10行8列的数据 则返回8行10列的数据

设置index(整体全部修改)

data.index = list 整体全部修改index 返回值为DataFrame 不改变原来的DataFrame
说明:按照列表list的数据内容修改index,必须整体全部修改
错误示例:data.index[3] = ‘学生_3’

重新设新的下标索引

data.reset_index(drop=True) 重新设新的下标索引 返回值为DataFrame 不改变原来的DataFrame
说明:drop:默认为False,不删除原来索引,如果为True,删除原来的索引值
一般适用于索引发生混乱的时候,给索引重新从0编号

把某列值设置为新的索引

data.set_index(keys, drop=True) 把某列值设置为新的索引 返回值为DataFrame 不改变原来的DataFrame
说明:keys : 列索引名成或者列索引名称的列表 drop: 默认为False,不删除原来索引,如果为True,删除原来的索引值

获取 DataFrame 的简要摘要

data.info() 返回DataFrame的一些基本信息

DataFrame的基本数据操作

操作代码实现返回值说明删除若干列df.drop([“a”,”b”,”c”], axis=1)新DataFrame不改变原来的DataFrame删除列数据del(df[‘G’])None改变原来的DataFrame增加列数据df[‘G’]=listDataFrame改变原来的DataFrame,list的长度必须的保持一致对某一列重新赋值df[‘G’]=100DataFrame改变原来的DataFrame对值排序df.sort_values(by=”open”, ascending=False)

df.sort_values(by=[‘open’, ‘high’])DataFrame改变原来的DataFrame

by:指定排序参考的键,单个键或者多个键进行排序

ascending:默认True升序,False降序对某一列重新赋值df[‘G’]=100DataFrame改变原来的DataFrame对索引排序df.sort_index()DataFrame改变原来的DataFrame

ascending:默认True升序,False降序

DataFrame的高级索引loc、iloc

loc函数:通过行索引 “Index” 中的具体值来取行数据(如取”Index”为”A”的行)
iloc函数:通过行号来取行数据(如取第二行的数据)
本章给出loc、iloc常见的五种用法,并附上详细代码。

1. 利用loc、iloc提取行数据
import numpy as np
import pandas as pd

data=pd.DataFrame(np.arange(16).reshape(4,4),index=list('abcd'),columns=list('ABCD'))

In[1]: data
Out[1]:
    A   B   C   D
a   0   1   2   3
b   4   5   6   7
c   8   9  10  11
d  12  13  14  15

In[2]: data.loc['a']
Out[2]:
A    0
B    1
C    2
D    3

In[3]: data.iloc[0]
Out[3]:
A    0
B    1
C    2
D    3
2. 利用loc、iloc提取列数据
In[4]:data.loc[:,['A']]
Out[4]:
    A
a   0
b   4
c   8
d  12
In[5]:data.iloc[:,'A':'C']
Out[5]:
    A   B   C
a   0   1   2
b   4   5   6
c   8   9   10
d   12  13  14

In[6]:data.iloc[:,[0]]
Out[6]:
    A
a   0
b   4
c   8
d  12
In[7]:data.iloc[:,0:2]
Out[7]:
    A   B
a   0   1
b   4   5
c   8   9
d   12  13
3.利用loc、iloc提取指定行、指定列数据
In[8]:data.loc[['a','b'],['A','B']]
Out[8]:
   A  B
a  0  1
b  4  5

In[9]:data.loc['b':'d','A':'C']
Out[9]:
    A   B   C
b   4   5   6
c   8   9   10
d   12  13  14

In[9]:data.iloc[[0,1],[0,1]]
Out[9]:
   A  B
a  0  1
b  4  5

In[10]:data.iloc[1:4,0:3]
Out[10]:
    A   B   C
b   4   5   6
c   8   9   10
d   12  13  14

4.利用loc、iloc提取所有数据
In[11]:data.loc[:,:]
Out[11]:
    A   B   C   D
a   0   1   2   3
b   4   5   6   7
c   8   9  10  11
d  12  13  14  15

In[12]:data.iloc[:,:]
Out[12]:
    A   B   C   D
a   0   1   2   3
b   4   5   6   7
c   8   9  10  11
d  12  13  14  15
5.利用loc函数,根据某个数据来提取数据所在的行
In[13]: data.loc[data['A']==0]
Out[13]:
   A  B  C  D
a  0  1  2  3

In[14]: data.loc[(data['A']==0)&(data['B']==2)]
Out[14]:
   A  B  C  D
a  0  1  2  3
同时,以下几种写法也可提取数据所在的行,与第五种用法类似,仅作补充。

In[15]: data[data['A']==0]
In[16]: data[data['A'].isin([0])]
In[17]: data[(data['A']==0)&(data['B']==2)]
In[18]: data[(data['A'].isin([0]))&(data['B'].isin([2]))]

Out[15]:
   A  B  C  D

DataFrame的运算

a. 运算函数

操作代码实现返回值说明算术运算df[‘open’].add(100)

df[‘open’].sub(100)新Series不改变原来的DataFrame,实际上是Series运算

add(100)是该列每一行的元素都+100

sub(100)是该列每一列的元素都-100逻辑运算df[“open”] > 100新Series(bool类型)不改变原来的DataFrame,返回值是True与Flase的Serise筛选df[df[“open”] > 23]

df[(df[“open”] > 23) & (df[“open”] < 24)]新DataFrame逻辑判断的结果可以作为筛选的依据筛选函数query()df.query(“open

b.统计运算函数

有时候我们获取到数据之后,想要查看下数据的简单统计指标(最大值、最小值、平均值、中位数等),比如想要查看年龄的最大值,如何实现呢?直接对 age 这一列调用 max方法即可。

user_info.age.max()

类似的,通过调用 minmeanquantilesum方法可以实现最小值、平均值、中位数以及求和

累加求和 cumsum ( )

来介绍个有意思的方法: cumsum,看名字就发现它和 sum 方法有关系,事实上确实如此, cumsum也是用来求和的,不过它是用来累加求和的,也就是说它得到的结果与原始的 DataFrame 大小相同。 cummax 最后的结果就是将上一次求和的结果与原始当前值求和作为当前值。 cumsum也可以用来操作字符串类型的对象。

一次性获取多个统计指标 describe( )

data.describe()
返回结果如图

pandas中DataFrame各种方法总结(持续更新)
如果想要查看非数字类型的列的统计指标,可以设置 include=["object"]来获得。
count:总数
unique:去重后的个数
top:出现频率最高的数
freq:出现的最高频率次数
user_info.describe(include=["object"])

pandas中DataFrame各种方法总结(持续更新)

统计下某列中每个值出现的次数 value_counts( )

调用 value_counts方法快速获取 DataFrame 中每个值出现的次数。

user_info.sex.value_counts()

获取某列最大值或最小值对应的索引 idxmax( ) /idxmin()

可以使用 idxmaxidxmin 方法完成

user_info.age.idxmax()

pandas中DataFrame各种方法总结(持续更新)

c.自定义运算

  • apply(func, axis=0)
    func:自定义函数;默认是列axis=0,对行进行运算axis=1。
    示例:对’open’, ‘close’两列进行自定义运算
>>>data[['open', 'close']].apply(lambda x: x.max() - x.min(), axis=0)
===运行结果:======================================
open     22.74
close    22.85
dtype: float64

d.逻辑运算

data[data[ column_1 ]== french ]
data[(data[ column_1 ]== french ) & (data[ year_born ]1990)]
data[(data[ column_1 ] french ) & (data[ year_born ]1990) & ~(data[ city ] London )]
通过逻辑运算来取数据子集。要使用 & (AND)、 ~ (NOT) 和 | (OR),必须在逻辑运算前后加上「and」。
data[data[ column_1 ].isin([ french , english ])]
除了可以在同一列使用多个 OR,你还可以使用.isin() 函数。

apply(),applymap(),map()函数

在Python中如果想要对数据使用函数,可以借助apply(),applymap(),map() 来应用函数,括号里面可以是直接函数式,或者自定义函数(def)或者匿名函数(lambad)

import pandas as pd
import numpy as np
from pandas import DataFrame
from pandas import Series
df1= DataFrame({
                "sales1":[-1,2,3],
                "sales2":[3,-5,7],
               })
df1

sales1  sales2
0   -1  3
1   2   -5
2   3   7

1、当我们要对数据框(DataFrame)的数据进行按行或按列操作时用apply()

df1.apply(lambda x :x.max()-x.min(),axis=1)

0    4
1    7
2    4
dtype: int64
df1.apply(lambda x :x.max()-x.min(),axis=0)

sales1     4
sales2    12
dtype: int64

关于axis参数的理解,请见我另一篇博客
2、当我们要对数据框(DataFrame)的每一个数据进行操作时用applymap(),返回结果是DataFrame格式

df1.applymap(lambda x : 1 if x>0 else 0)

sales1  sales2
0   0   1
1   1   0
2   1   1

3、当我们要对Series的每一个数据进行操作时用map()

df1["sales1"].map(lambda x : 1 if x>0 else 0)

0    0
1    1
2    1
Name: sales1, dtype: int64

补充:在处理大规模数据集时,pandas 会花费一些时间来进行.map()、.apply()、.applymap() 等操作。tqdm 是一个可以用来帮助预测这些操作的执行何时完成的包(是的,我说谎了,我之前说我们只会使用到 pandas)。

from tqdm import tqdm_notebook
tqdm_notebook().pandas()

用 pandas 设置 tqdm

data[ column_1 ].progress_map(lambda x: x.count( e ))

用 .progress_map() 代替.map()、.apply() 和.applymap() 也是类似的。在 Jupyter 中使用 tqdm 和 pandas 得到的进度条

pandas中DataFrame各种方法总结(持续更新)
tqdm会有另外的专题详细介绍,还没更新。

数据合并(concat,merge)

数据如下:

left = pd.DataFrame({'key1': ['K0', 'K0', 'K1', 'K2'],
                     'key2': ['K0', 'K1', 'K0', 'K1'],
                     'A': ['A0', 'A1', 'A2', 'A3'],
                     'B': ['B0', 'B1', 'B2', 'B3']})

right = pd.DataFrame({'key1': ['K0', 'K1', 'K1', 'K2'],
                      'key2': ['K0', 'K0', 'K0', 'K0'],
                      'C': ['C0', 'C1', 'C2', 'C3'],
                      'D': ['D0', 'D1', 'D2', 'D3']})

pd.concat实现数据合并

pd.concat([data1, data2], axis=1)
axis=0 跨行操作,行变列不变
axis=1 跨列操作,列变行不变

pd.concat([left,right],axis=1)

   key1 key2 A  B  key1 key2 C   D
0   K0  K0  A0  B0  K0  K0  C0  D0
1   K0  K1  A1  B1  K1  K0  C1  D1
2   K1  K0  A2  B2  K1  K0  C2  D2
3   K2  K1  A3  B3  K2  K0  C3  D3

pd.concat([left,right],axis=0)

   key1 key2 A   B   C   D
0   K0  K0  A0  B0  NaN NaN
1   K0  K1  A1  B1  NaN NaN
2   K1  K0  A2  B2  NaN NaN
3   K2  K1  A3  B3  NaN NaN
0   K0  K0  NaN NaN C0  D0
1   K1  K0  NaN NaN C1  D1
2   K1  K0  NaN NaN C2  D2
3   K2  K0  NaN NaN C3  D3

pandas中DataFrame各种方法总结(持续更新)

pd.merge实现数据合并

pd.merge(left, right, how='inner', on=None)
可以指定按照两组数据的共同键值对合并或者左右各自
left: DataFrame
right: 另一个DataFrame
on: 指定的共同键
how:按照什么方式连接

a.内连接

查询两个表中符合条件的共有记录
如图:

pandas中DataFrame各种方法总结(持续更新)
pandas中DataFrame各种方法总结(持续更新)

; b.外连接

两个表中所有记录都保留;两个表不存在的数据,使用np.NaN值填充。

pandas中DataFrame各种方法总结(持续更新)

c.左连接

以左表为主,根据条件查询右表数据;左表数据全部保留,右表不存在的数据,使用np.NaN值填充。

pandas中DataFrame各种方法总结(持续更新)
pandas中DataFrame各种方法总结(持续更新)

; d.右连接

以右表为主,根据条件查询左表数据;右表数据全部保留,左表不存在的数据,使用np.NaN值填充

pandas中DataFrame各种方法总结(持续更新)
pandas中DataFrame各种方法总结(持续更新)

分组和聚合

DataFrame.groupby(key, as_index=False)key:分组的列数据,可以多个
案例:不同颜色的不同笔的价格数据
进行分组,对颜色分组,对价格进行聚合

>>>col =pd.DataFrame({'color': ['white','red','green','red','green'],
                      'object': ['pen','pencil','pencil','ashtray','pen'],
                      'price1':[5.56,4.20,1.30,0.56,2.75],
                      'price2':[4.75,4.12,1.60,0.75,3.15]})

     color    object    price1    price2
0    white    pen       5.56    4.75
1    red      pencil    4.20    4.12
2    green    pencil    1.30    1.60
3    red      ashtray   0.56    0.75
4    green    pen       2.75    3.15

颜色分组 价格聚合

>>>col.groupby(['color'])['price1'].mean()

color
green    2.025
red      2.380
white    5.560
Name: price1, dtype: float64

>>>col['price1'].groupby(col['color']).mean()

color
green    2.025
red      2.380
white    5.560
Name: price1, dtype: float64

添加参数as_index=False后,注意数据的结构的变化

>>>col.groupby(['color'], as_index=False)['price1'].mean()

     color    price1
0    green    2.025
1    red      2.380
2    white    5.560

agg()—- aggregation聚合函数 (没怎么用过)

dataset.groupby('color').agg([list])

交叉表与透视表(没怎么用过)

交叉表:用于计算一列数据对于另外一列数据的分组个数(用于统计分组频率的特殊透视表)

pd.crosstab(df["A"], df["B"])

透视表:透视表是将原有的DataFrame的列分别作为行索引和列索引,然后对指定的列应用聚集函数

dataframe.pivot_table([], index=[])

实操中遇到的问题及其解决办法

统计某列无重复的值

dataframe['列名'].unique()

统计指定列不重复的值的数目

方法一 duplicated

&#x65B9;&#x6CD5;:
   DataFrame.duplicated&#xFF08;subset = None&#xFF0C;keep =&#x2018;first&#x2019; &#xFF09;&#x8FD4;&#x56DE;boolean&#x6570;&#x7EC4; &#x4E00;&#x4E2A;bool&#x503C;&#x4EE3;&#x8868;&#x4E00;&#x884C;
&#x53C2;&#x6570;&#xFF1A;
   subset&#xFF1A;&#x7528;&#x6765;&#x6307;&#x5B9A;&#x7279;&#x5B9A;&#x7684;&#x5217;&#xFF0C;&#x9ED8;&#x8BA4;&#x6240;&#x6709;&#x5217;

   keep&#xFF1A;{&#x2018;first&#x2019;&#xFF0C;&#x2018;last&#x2019;&#xFF0C;False}&#xFF0C;&#x9ED8;&#x8BA4;&#x2019;first&#x2019;
   first&#xFF1A;&#x6807;&#x8BB0;&#x91CD;&#x590D;&#xFF0C;True&#x9664;&#x4E86;&#x7B2C;&#x4E00;&#x6B21;&#x51FA;&#x73B0;&#x3002;
   last&#xFF1A;&#x6807;&#x8BB0;&#x91CD;&#x590D;&#xFF0C;True&#x9664;&#x4E86;&#x6700;&#x540E;&#x4E00;&#x6B21;&#x51FA;&#x73B0;&#x3002;
   False&#xFF1A;&#x5C06;&#x6240;&#x6709;&#x91CD;&#x590D;&#x9879;&#x6807;&#x8BB0;&#x4E3A;True&#x3002;

pandas中DataFrame各种方法总结(持续更新)
import pandas as pd
if __name__=="__main__":
    path = "./test.csv"

    df = pd.read_csv(path, header=0, names=["DEVICE_ID","LNG", "LAT","TEN_GROUP","WEEKDAY","FLOW"])

    print("DEVICE_ID列不同值数目:\n%s\n\n" % str(len(df['DEVICE_ID'].unique())))

    t=df.duplicated(subset=["DEVICE_ID"],keep=False)
    print(t)

    print(len(t[t==False]))

    print("不重复键:")
    print(df[~t])

DEVICE_ID列不同值数目:3
0      True
1      True
2      True
3      True
4      True
5      True
6      True
7      True
8      True
9      True
10     True
11     True
12     True
13    False
dtype: bool
1
不重复键:
    DEVICE_ID    LNG   LAT  TEN_GROUP  WEEKDAY FLOW
13          3  123.0  43.0        102        1   29

方法二 value_counts()

df["DEVICE_ID"].value_counts()

遍历dataframe的每一行方法比较总结

数据初始化

import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(10, size=(1000000, 1)), columns=['num'])

下标遍历

(不建议使用)

for i in range(len(df)):
    if df.iloc[i]['num'] < 5:
        df.loc[i , 'num'] = 15

iterrows遍历

原理是将Dataframe迭代为Series,再返回结果。这一过程中需要进行类型检查,所以,会花费很长的时间。(不建议使用)

for index, row in df.iterrows():
    if row['num'] < 5:
        df.loc[index , 'num'] = 15

itertuples()

原理是将Dataframe迭代为tuple,再进行返回,由于元组不可变的特性,此过程不需要进行类型检查。(效率高,推荐使用)

for row in student.itertuples():

    print(row.Index, row.name, row.account, row.pwd)
    print(row.Index, getattr(row,'name'), getattr(row,'account'), getattr(row,'pwd'))

for + zip

这种方法是直接手动构造原生tuple,无需关心index数据。(效率高,推荐使用)

for A, B in zip(df['A'], df['B']):
    print(A, B)

SettingWithCopyWarning警告

这段时间一直在用pandas,今天运行前人代码发现报了一个warning:

SettingWithCopyWarning: A value is trying to be set on a copy of a
slice from a DataFrame See the caveats in the documentation:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

SettingWithCopyWarning出现的原因

链式赋值/Chained Assignment

SettingWithCopyWarning会在什么时候出现呢,简而言之就是在链式赋值的时候出现。
以下例子数据以此为例:

df1 = pd.DataFrame(np.random.random(20).reshape((10,2)), columns=list('AB'))
df1

pandas中DataFrame各种方法总结(持续更新)

什么是链式

链式就是进行多次同类型的操作,比如a = b = c = 4就是一个链式操作。在这里的链式操作主要是指,对于一个pandas格式的表,选取两次或者以上次数的其中结果。
比如选取其中A值小于0.3的行得到:

df1[df1.A < 0.3]

那么选取其中所有A

Original: https://blog.csdn.net/weixin_44217936/article/details/116700074
Author: 想躺平的小陈
Title: pandas中DataFrame各种方法总结(持续更新)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/750875/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球