Pandas简介 文件的读取与数据创建 读取CSV文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import pandas as pddf = pd.read_csv( "./路径/文件.csv" , encoding='utf-8' , index_col=None , sep=',' , usecols=None , names=None ) df_tsv = pd.read_csv( "./路径/文件.tsv" , sep='\t' ) df_txt = pd.read_csv( './路径/文件.txt' , sep='\t' , header=0 , names=['字段1' , '字段2' ] )
存储CSV文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 df.to_csv("./路径/文件.csv" ) df.to_csv( "./路径/文件.tsv" , sep='\t' , index=False ) df.to_csv( "./路径/文件.txt" , sep='\t' , index=False )
对于处理Excel文件、JSON数据、以及与MySQL数据库交互的操作,我们可以整理和规范化代码示例,以提供清晰的指导。
处理Excel文件 读取Excel文件 1 2 3 4 5 6 7 8 9 import pandas as pddf = pd.read_excel( "./路径/文件.xlsx" , engine="openpyxl" , sheet_name='Sheet1' , header=0 )
存储为Excel文件 1 2 3 4 5 6 df.to_excel( './路径/文件.xlsx' , sheet_name='Sheet1' , index=False )
处理JSON数据 读取JSON数据 1 2 3 4 5 6 df_from_file = pd.read_json('./路径/文件.json' ) URL = 'https://example.com/data.json' df_from_url = pd.read_json(URL)
存储为JSON文件 1 2 df.to_json('./路径/文件.json' )
与MySQL数据库交互 读取MySQL数据库数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import pandas as pdimport mysql.connectorcnx = mysql.connector.connect( user='用户名' , password='密码' , host='主机地址' , database='数据库名' , charset='utf8' ) query = "SELECT * FROM 表名" df = pd.read_sql(query, cnx) cnx.close()
存储数据到MySQL数据库 1 2 3 4 5 6 7 8 9 10 11 12 from sqlalchemy import create_engineengine = create_engine('mysql+mysqlconnector://用户名:密码@主机地址/数据库名' ) df.to_sql( 'tablename' , con=engine, if_exists='replace' , index=False )
对于创建Pandas Series的基础知识和示例代码,我们可以进行以下整理以提供清晰、规范的说明和操作步骤。
创建Pandas Series Series的特点
索引(Index) : 每个Series对象都有一个索引,用于标识每个数据点。索引的类型可以是整数、字符串、日期等。如果创建Series时未显式指定索引,Pandas会自动生成一个从0开始的整数索引。
数据类型(Datatype) : Series可以包含各种类型的数据(整数、浮点数、字符串等)。Pandas允许Series内的数据类型不同,但通常情况下,为了效率,Series中的数据类型会保持一致。
灵活性 : Series支持多种操作,包括数学运算、索引/选择、数据对齐等。
基础语法 创建Series的基础语法如下:
1 pandas.Series(data=None , index=None , dtype=None , name=None , copy=False )
参数说明
data : 可以是列表、数组等形式的数据集合。这是Series中存储的主要数据。
index : 与数据同长度的索引标签列表。如果未指定,将自动生成从0开始的整数索引。
dtype : 数据的类型(如int
, float
, str
等)。如果未指定,dtype将自动推断。
name : 为Series指定一个名称,便于理解和输出显示。
copy : 是否复制输入数据,默认为False
。设置为True
可以避免修改原始数据。
创建Series示例 示例1: 使用列表创建Series 1 2 3 4 5 import pandas as pddata = [1 , 2 , 3 ] series = pd.Series(data) print (series)
示例2: 使用NumPy数组创建Series 1 2 3 4 5 6 import pandas as pdimport numpy as npdata = np.array([1 , 2 , 3 ]) series = pd.Series(data) print (series)
在这两个示例中,我们创建了包含三个整数的Series对象。由于未指定索引,Pandas自动生成了从0开始的整数索引。这些示例展示了如何从基本的数据结构(列表或NumPy数组)创建Series,并展示了Series的基础属性,如自动索引和数据类型推断。
使用Pandas Series时,索引是一个强大的特性,允许快速访问、修改数据。以下是如何使用索引获取数据和指定索引的整理和示例。
使用索引获取数据 当创建一个Pandas Series对象时,每个元素都会自动分配一个索引。这个索引可以是默认的整数索引,也可以是自定义的索引。
示例1: 使用默认整数索引获取数据 1 2 3 4 5 6 7 8 import pandas as pddata = [1 , 2 , 3 ] series = pd.Series(data) print (series[1 ])
此代码会输出Series中索引为1的元素,即2
。
指定索引 可以在创建Series时通过index
参数自定义索引。
示例2: 使用自定义索引 1 2 3 4 5 6 7 8 import pandas as pddata = ["Google" , "Runoob" , "Wiki" ] series = pd.Series(data, index=["x" , "y" , "z" ]) print (series)
输出结果将展示一个Series,其中每个元素都由指定的索引标记:
1 2 3 4 x Google y Runoob z Wiki dtype: object
在这个例子中,字符串"Google"
, "Runoob"
, "Wiki"
分别被赋予了自定义索引"x"
, "y"
, "z"
。通过指定索引,可以提高数据检索的可读性和灵活性。
当创建Pandas Series时,指定索引和使用键值对(类似于字典)作为数据源是两种常见的方法。这提供了灵活的数据结构创建和数据访问方式。下面是对这些概念的整理和示例说明。
示例3: 使用自定义索引访问数据 1 2 3 4 5 6 7 8 import pandas as pddata = ["Google" , "Runoob" , "Wiki" ] series = pd.Series(data, index=["x" , "y" , "z" ]) print (series["y" ])
此代码段会输出索引为"y"
的元素,即"Runoob"
。
使用字典创建Series 当使用字典创建Series时,字典的键自动成为Series的索引,而字典的值成为Series的数据。
示例1: 从字典创建Series 1 2 3 4 5 6 7 8 import pandas as pdsites = {1 : "Google" , 2 : "Runoob" , 3 : "Wiki" } series = pd.Series(sites) print (series)
这段代码创建了一个Series,其中字典的键(1, 2, 3)自动成为了Series的索引。
示例2: 指定索引过滤数据 如果在使用字典创建Series时还指定了index
参数,那么只有在index
参数中指定的键会被包含在Series中。
1 2 3 4 5 6 7 8 import pandas as pdsites = {1 : "Google" , 2 : "Runoob" , 3 : "Wiki" } series = pd.Series(sites, index=[1 , 2 ]) print (series)
这段代码将只输出键为1和2的数据项,即"Google"
和"Runoob"
,因为在创建Series时我们通过index
参数指定了只包含这些键。
在处理Pandas Series时,了解如何设置名称、执行基本操作、进行基本运算、以及使用属性和方法是非常重要的。以下是对这些概念的整理和示例说明。
设置Series名称参数 可以在创建Series时通过name
参数为Series设置一个名称,这有助于标识Series代表的数据集。
1 2 3 4 5 6 import pandas as pdsites = {1 : "Google" , 2 : "Runoob" , 3 : "Wiki" } myvar = pd.Series(sites, index=[1 , 2 ], name="RUNOOB-Series-TEST" ) print (myvar)
基本操作 获取值 1 2 3 4 5 value = myvar[2 ] subset = myvar[1 :3 ]
遍历Series 1 2 3 for index, value in myvar.items(): print (f"Index: {index} , Value: {value} " )
基本运算 算术运算
过滤 1 2 filtered_series = myvar[myvar > 2 ]
应用数学函数 1 2 3 4 import numpy as npresult = np.sqrt(myvar)
属性和方法 获取索引和值 1 2 3 4 5 index = myvar.index values = myvar.values
描述统计 1 2 3 4 5 6 7 data = {'name' : ['Alice' , 'Bob' , 'Charlie' , 'David' , 'Emily' ], 'score' : [90 , 85 , 75 , 80 , 95 ], 'age' : [20 , 25 , 30 , 35 , 40 ]} df = pd.DataFrame(data) stats = df.describe() print (stats)
获取最大值和最小值的索引 1 2 3 max_index = myvar.idxmax() min_index = myvar.idxmin()
DataFrame Pandas的DataFrame
是一个二维的、大小可变的、潜在的异构表格数据结构,带有标记的轴(行和列)。理解DataFrame
的基础语法和创建方法是使用Pandas进行数据分析和数据处理的基础。
基础语法 创建DataFrame
的基础语法如下:
1 pandas.DataFrame(data=None , index=None , columns=None , dtype=None , copy=False )
参数说明
data : 接受多种类型的输入,包括但不限于ndarray
、Series
、map
、lists
、dict
等。这是DataFrame
中存储的主要数据。
index : 行标签。如果没有指定,就像在Series
中一样,Pandas会默认创建从0开始的整数索引。
columns : 列标签,默认为RangeIndex (0, 1, 2, …, n)
。如果数据输入是字典,则默认列标签是字典键排序后的顺序。
dtype : 数据类型。可以为整个DataFrame
指定一个统一的数据类型。如果不指定,则会自动推断。
copy : 是否复制输入数据,默认为False
。如果为True
,则复制,这可以避免修改到原始数据。
创建DataFrame示例 通过列表创建DataFrame
1 2 3 4 5 6 7 8 9 10 import pandas as pddata = [['Google' , 10 ], ['Runoob' , 12 ], ['Wiki' , 13 ]] df = pd.DataFrame(data, columns=['Site' , 'Age' ], dtype=float ) print (df)
输出结果将是一个DataFrame
,包含两列Site
和Age
,数据类型被设置为浮点数:
1 2 3 4 Site Age 0 Google 10.0 1 Runoob 12.0 2 Wiki 13.0
在这个例子中,data
是一个列表,其中包含三个子列表,每个子列表代表一行数据。通过columns
参数指定了列名为Site
和Age
,通过dtype
参数将所有数值数据类型指定为浮点数。
在Pandas中,DataFrame
是用于存储和操作结构化数据的主要数据结构。以下内容整理了DataFrame
的创建、基本操作、属性和方法,以及如何从外部数据源创建DataFrame
的相关信息。
通过ndarrays或列表的字典创建 1 2 3 4 5 6 import pandas as pddata = {'Site' : ['Google' , 'Runoob' , 'Wiki' ], 'Age' : [10 , 12 , 13 ]} df = pd.DataFrame(data) print (df)
输出结果:
1 2 3 4 Site Age 0 Google 10 1 Runoob 12 2 Wiki 13
通过字典列表创建 1 2 3 4 data = [{'a' : 1 , 'b' : 2 }, {'a' : 5 , 'b' : 10 , 'c' : 20 }] df = pd.DataFrame(data) print (df)
输出结果:
1 2 3 a b c 0 1 2 NaN 1 5 10 20.0
注意:缺失的数据部分为NaN
,而非NULL
。
loc 属性返回指定行的数据首先,导入Pandas库,并创建一个包含数据的字典,然后将其载入到DataFrame
对象中。默认情况下,如果没有指定索引,Pandas会自动创建一个从0开始的整数索引。
1 2 3 4 5 6 7 8 import pandas as pddata = { "calories" : [420 , 380 , 390 ], "duration" : [50 , 40 , 45 ] } df = pd.DataFrame(data)
返回单行数据 使用loc
属性,可以通过指定行索引来返回对应的数据行。此时,返回的结果是一个Pandas Series
数据类型。
返回多行数据 loc
同样可以用于返回多行数据,通过传递一个包含多个索引的列表作为参数。
使用自定义索引 Pandas允许为DataFrame
对象的行设置自定义索引。
1 2 df = pd.DataFrame(data, index = ["day1" , "day2" , "day3" ]) print (df)
使用自定义索引后,可以使用这些索引值来检索数据行。
在这个例子中,我们首先设置了自定义索引(”day1”, “day2”, “day3”),然后通过这些索引来检索数据。当使用loc
与自定义索引时,指定的索引值必须存在于DataFrame
的索引中,否则会引发KeyError
。
在使用Pandas处理数据时,DataFrame
是一个非常核心的数据结构,它允许以表格的形式存储和操作结构化数据。以下是对提供的代码和概念的整理和解释,帮助更好地理解如何使用DataFrame
进行基本操作、属性和方法的调用、数据操作技巧,以及如何从外部数据源创建DataFrame
。
基本操作 获取列 1 name_column = df['Name' ]
获取行
选择多列 1 subset = df[['Name' , 'Age' ]]
过滤行 1 filtered_rows = df[df['Age' ] > 30 ]
属性和方法 获取列名
获取形状(行数和列数)
获取索引
获取描述统计信息
数据操作 添加新列 1 df['Salary' ] = [50000 , 60000 , 70000 ]
删除列 1 df.drop('City' , axis=1 , inplace=True )
排序 1 df.sort_values(by='Age' , ascending=False , inplace=True )
重命名列 1 df.rename(columns={'Name' : 'Full Name' }, inplace=True )
从外部数据源创建 DataFrame 从CSV文件创建 1 df_csv = pd.read_csv('example.csv' )
从Excel文件创建 1 df_excel = pd.read_excel('example.xlsx' )
从字典列表创建 1 2 data_list = [{'Name' : 'Alice' , 'Age' : 25 }, {'Name' : 'Bob' , 'Age' : 30 }] df_from_list = pd.DataFrame(data_list)
灵活性 :DataFrame
可以容纳不同数据类型的列(例如整数、浮点数、字符串等)。
索引 :列名和行索引可以是字符串、整数等。Pandas提供了丰富的索引功能,以便于数据选择和操作。
数据操作 :可以通过多种方式进行数据选择、过滤、修改和分析,这使得DataFrame
非常适合数据清洗、转换、分析和可视化等工作。
案例 缺失率 缺失率是指在数据集中缺失值所占的比例,通常用于数据清洗和预处理阶段,以评估数据的完整性。计算缺失率的基本公式如下:
$$ \text{缺失率 (%)} = \left( \frac{\text{缺失值数量}}{\text{总值数量}} \right) \times 100 $$
其中,
数据集中的缺失值数量是指那些空白或者NULL值的数量。
数据集中的总值数量是指数据集中所有可能的数据点的数量,包括有效值和缺失值。
缺失率可以帮助我们了解数据缺失的严重程度,进而决定如何处理这些缺失值,比如通过删除缺失值、填补缺失值或者采用模型估计等方法。
创建数据表 在这个DataFrame
中,包含了几个列:id
、date
、city
、age
、category
,以及price
。
1 2 3 4 5 6 7 8 9 10 11 import pandas as pdimport numpy as npdf = pd.DataFrame({ "id" : [1001 , 1002 , 1003 , 1004 , 1005 , 1006 ], "date" : pd.date_range('20130102' , periods=6 ), "city" : ['Beijing ' , 'SH' , ' guangzhou ' , 'Shenzhen' , 'shanghai' , 'BEIJING ' ], "age" : [23 , 44 , 54 , 32 , 34 , 32 ], "category" : ['100-A' , '100-B' , '110-A' , '110-C' , '210-A' , '130-F' ], "price" : [1200 , np.nan, 2133 , 5433 , np.nan, 4432 ] }, columns=['id' , 'date' , 'city' , 'category' , 'age' , 'price' ])
这段代码首先导入了必要的库:pandas
和numpy
。numpy
在这里的用途是提供np.nan
来表示缺失值,这在处理真实世界的数据时非常常见。
id
列包含唯一标识符。
date
列使用pd.date_range
函数生成了一个日期范围。
city
列包含了一些城市名称,注意这些城市名称前后可能包含空格。
age
列包含了年龄。
category
列包含了分类代码。
price
列包含了价格,使用np.nan
表示某些价格未知或缺失。
通过指定columns
参数,确保了DataFrame
列的顺序按照id
、date
、city
、category
、age
、price
的顺序排列,即使在字典中的顺序不是这样的。
数据概览
id date city category age price
0 1001 2013-01-02 Beijing 100-A 23 1200.0
1 1002 2013-01-03 SH 100-B 44 NaN
2 1003 2013-01-04 guangzhou 110-A 54 2133.0
3 1004 2013-01-05 Shenzhen 110-C 32 5433.0
4 1005 2013-01-06 shanghai 210-A 34 NaN
5 1006 2013-01-07 BEIJING 130-F 32 4432.0
每列缺失值的数量 1 2 3 missing_values_count = df.isnull().sum () print (missing_values_count)
id 0
date 0
city 0
category 0
age 0
price 2
dtype: int64
1 2 3 4 显示所有的数据 pd.set_option('display.max_rows' , None ) pd.set_option('display.max_columns' , None ) pd.set_option('expand_frame_repr' , False )
缺失率 1 2 3 missing_rate = (missing_values_count / len (df)) * 100 print (missing_rate)
id 0.000000
date 0.000000
city 0.000000
category 0.000000
age 0.000000
price 33.333333
dtype: float64
DataFrame常规操作 修改index、columns 修改DataFrame的索引(index
) 在Pandas中,修改DataFrame的索引是一个常见操作,可以帮助更好地定位和引用数据行。下面是如何修改DataFrame索引的步骤和示例:
设置默认显示行数 :首先,我们可以通过pd.set_option
来设置Pandas默认显示的行数。这里未展示设置方法,但可以通过print(df.head())
来显示前几行数据,其中df
是DataFrame变量名。
直接修改索引 :可以通过直接赋值给df.index
属性来修改整个DataFrame的索引。例如,如果有一个DataFrame row
,并且想要将索引修改为['x', 'y', 'z']
,需要确保索引的长度与DataFrame的行数相匹配。如果不匹配,会导致错误。
1 row.index = ['x' , 'y' , 'z' ]
读取文件时只处理部分行 当处理大型文件时,为了测试或其他目的,可能只想读取文件的一部分。使用pd.read_csv
时,可以通过nrows
参数来限制读取的行数。
1 df = pd.read_csv('./LCIS.csv' , nrows=3 )
修改DataFrame的列名(columns
) 修改列名可以通过直接赋值给df.columns
属性或使用rename
方法。
直接修改所有列名 :通过直接赋值给df.columns
属性,可以为所有列设置新的列名。
1 row.columns = ['A' , 'B' , 'C' ]
使用rename
方法修改列名 :如果只想修改某些列的名称,可以使用rename
方法,并通过columns
参数传入一个字典,字典的键是旧列名,值是新列名。使用inplace=True
可以直接在原DataFrame上进行修改,而不是返回一个新的DataFrame。
1 row.rename(columns={'ListingId' : 'ID' }, inplace=True )
单独修改一个索引或列名 同样,使用rename
方法也可以修改单个索引或列名,方法与修改列名类似。
1 row.rename(index={0 : 'A' }, inplace=True )
综合示例 现在,让我们通过一个综合示例来展示如何实际应用上述操作,并提供预期的输出结果。
数据导入 1 2 3 import pandas as pddf = pd.read_csv('LCIS.csv' ,nrows=5 , usecols=range (10 )) row = pd.DataFrame(df)
修改索引前的输出 1 2 print ("修改索引前:" )print (row.head())
1 2 3 4 5 6 7 修改索引前: ListingId 借款金额 借款期限 借款利率 借款成功日期 初始评级 借款类型 是否首标 年龄 性别 0 1693100 3629 6 12 2015/1/28 AA 普通 否 31 男 1 1713229 3000 12 12 2015/1/30 AA 普通 是 24 男 2 1904026 3629 12 12 2015/3/7 AA 普通 否 27 男 3 2158281 3919 12 18 2015/4/14 C 普通 否 28 男 4 2257194 14000 12 18 2015/4/23 C 普通 否 46 男
修改索引后的输出 1 2 3 4 row.index = ['x' , 'y' , 'z' , 'a' , 'b' ] print ("\n修改索引后:" )print (row.head())
1 2 3 4 5 6 7 修改索引后: ListingId 借款金额 借款期限 借款利率 借款成功日期 初始评级 借款类型 是否首标 年龄 性别 x 1693100 3629 6 12 2015/1/28 AA 普通 否 31 男 y 1713229 3000 12 12 2015/1/30 AA 普通 是 24 男 z 1904026 3629 12 12 2015/3/7 AA 普通 否 27 男 a 2158281 3919 12 18 2015/4/14 C 普通 否 28 男 b 2257194 14000 12 18 2015/4/23 C 普通 否 46 男
修改列名 1 2 3 4 row.columns = ['A' , 'B' , 'C' , 'D' , 'E' , 'F' , 'G' , 'H' , 'I' , 'J' ] print ("\n修改列名后:" )print (row.head())
1 2 3 4 5 6 7 修改列名后: A B C D E F G H I J x 1693100 3629 6 12 2015/1/28 AA 普通 否 31 男 y 1713229 3000 12 12 2015/1/30 AA 普通 是 24 男 z 1904026 3629 12 12 2015/3/7 AA 普通 否 27 男 a 2158281 3919 12 18 2015/4/14 C 普通 否 28 男 b 2257194 14000 12 18 2015/4/23 C 普通 否 46 男
使用rename方法重命名列 1 2 3 4 row.rename(columns={'A' : 'ID' }, inplace=True ) print ("\n使用rename方法修改列名后:" )print (row)
1 2 3 4 5 6 7 使用rename方法修改列名后: ID B C D E F G H I J x 1693100 3629 6 12 2015/1/28 AA 普通 否 31 男 y 1713229 3000 12 12 2015/1/30 AA 普通 是 24 男 z 1904026 3629 12 12 2015/3/7 AA 普通 否 27 男 a 2158281 3919 12 18 2015/4/14 C 普通 否 28 男 b 2257194 14000 12 18 2015/4/23 C 普通 否 46 男
单独修改一个索引 1 2 3 4 row.rename(index={'x' : 'A' }, inplace=True ) print ("\n单独修改一个索引后:" )print (row)
1 2 3 4 5 6 7 单独修改一个索引后: ID B C D E F G H I J A 1693100 3629 6 12 2015/1/28 AA 普通 否 31 男 y 1713229 3000 12 12 2015/1/30 AA 普通 是 24 男 z 1904026 3629 12 12 2015/3/7 AA 普通 否 27 男 a 2158281 3919 12 18 2015/4/14 C 普通 否 28 男 b 2257194 14000 12 18 2015/4/23 C 普通 否 46 男
数据合并 concat()
函数概览pd.concat()
可以沿着一条轴将多个对象堆叠到一起。主要参数包括:
objs
:一个序列或映射,表示要合并的pandas对象。
axis
:默认为0,表示沿着行合并;设置为1表示沿着列合并。
ignore_index
:如果为True,不使用索引标签进行连接;这将对结果DataFrame使用默认整数索引。
在Pandas中,pd.concat()
函数是合并数据的一个非常有用的工具,它允许沿着特定的轴将多个DataFrame合并在一起。下面,我们将通过具体的示例来展示如何使用pd.concat()
进行数据合并,包括沿着列(axis=1)和沿着行(axis=0)的合并。每个案例都将提供代码示例和预期的输出结果。
示例数据 选择性读取行 有时候,在读取文件创建DataFrame时,可能想要跳过某些行或只读取特定的行。可以通过skiprows
和nrows
参数来实现这一点:
1 2 3 df = pd.read_csv('./LCIS.csv' , skiprows=range (1 , 4 ), nrows=3 , usecols=range (2 , 6 )) res = pd.DataFrame(df) print (res)
这里,skiprows=range(1, 4)
跳过了文件的第1到第3行(注意行数是从0开始计数的),而nrows=3
指定了之后只读取3行。
1 2 3 4 借款期限 借款利率 借款成功日期 初始评级 0 12 18 2015/4/14 C 1 12 18 2015/4/23 C 2 6 15 2015/4/29 B
首先,让我们定义两个DataFrame,row
和res
,以便进行合并操作。假设这些DataFrame已经根据上文中的说明进行了加载和修改:
1 2 3 4 5 6 7 8 9 10 11 12 import pandas as pdrow = pd.read_csv('LCIS.csv' , skiprows=range (1 , 11 ), header=0 , nrows=10 , usecols=range (10 )) res = pd.read_csv('LCIS.csv' ,skiprows=range (12 , 20 ), header=0 , nrows=10 , usecols=range (10 )) print ('row DataFrame' )print (row)print ("=============================================" )print ('res DataFrame' )print (res)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 row DataFrame ListingId 借款金额 借款期限 借款利率 借款成功日期 初始评级 借款类型 是否首标 年龄 性别 0 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 男 1 2707322 5000 3 10.0 2015/6/5 AA 普通 否 35 男 2 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 男 3 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 男 4 2850335 17640 18 16.0 2015/6/18 B 其他 是 28 男 5 3155520 7008 10 11.0 2015/7/12 AA 普通 否 34 男 6 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 男 7 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 男 8 3637812 4000 6 10.5 2015/8/17 AA 其他 是 24 男 9 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 男 ============================================= res DataFrame ListingId 借款金额 借款期限 借款利率 借款成功日期 初始评级 借款类型 是否首标 年龄 性别 0 1693100 3629 6 12 2015/1/28 AA 普通 否 31 男 1 1713229 3000 12 12 2015/1/30 AA 普通 是 24 男 2 1904026 3629 12 12 2015/3/7 AA 普通 否 27 男 3 2158281 3919 12 18 2015/4/14 C 普通 否 28 男 4 2257194 14000 12 18 2015/4/23 C 普通 否 46 男 5 2272036 40000 6 15 2015/4/29 B 电商 是 32 男 6 2315058 3200 3 10 2015/4/29 AA 普通 否 25 男 7 2332817 3000 6 12 2015/5/6 AA 普通 是 38 男 8 2365175 4260 7 12 2015/5/6 AA 普通 否 25 男 9 2370723 11987 12 16 2015/5/7 B 其他 否 33 女
沿着列合并DataFrame 当想要将两个DataFrame按列拼接(即并排放置),可以设置axis=1
。这通常用于合并具有相同索引的DataFrame,但列不同的情况。
1 2 num = pd.concat([row, res], axis=1 ) print (num)
预期输出是row
和res
DataFrame并排放置的结果,这里由于row
和res
的行数相同,因此可以直接并排合并。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ListingId 借款金额 借款期限 借款利率 借款成功日期 初始评级 借款类型 是否首标 年龄 性别 ListingId \ 0 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 男 1693100 1 2707322 5000 3 10.0 2015/6/5 AA 普通 否 35 男 1713229 2 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 男 1904026 3 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 男 2158281 4 2850335 17640 18 16.0 2015/6/18 B 其他 是 28 男 2257194 5 3155520 7008 10 11.0 2015/7/12 AA 普通 否 34 男 2272036 6 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 男 2315058 7 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 男 2332817 8 3637812 4000 6 10.5 2015/8/17 AA 其他 是 24 男 2365175 9 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 男 2370723 借款金额 借款期限 借款利率 借款成功日期 初始评级 借款类型 是否首标 年龄 性别 0 3629 6 12 2015/1/28 AA 普通 否 31 男 1 3000 12 12 2015/1/30 AA 普通 是 24 男 2 3629 12 12 2015/3/7 AA 普通 否 27 男 3 3919 12 18 2015/4/14 C 普通 否 28 男 4 14000 12 18 2015/4/23 C 普通 否 46 男 5 40000 6 15 2015/4/29 B 电商 是 32 男 6 3200 3 10 2015/4/29 AA 普通 否 25 男 7 3000 6 12 2015/5/6 AA 普通 是 38 男 8 4260 7 12 2015/5/6 AA 普通 否 25 男 9 11987 12 16 2015/5/7 B 其他 否 33 女
沿着行合并DataFrame 如果想将两个DataFrame上下拼接,可以设置axis=0
。这通常用于合并具有相同列的DataFrame,或者即使列不完全相同也可以合并,Pandas会自动处理不匹配的列。
1 2 num = pd.concat([row, res], axis=0 ) print (num)
在这个例子中,由于res
仅包含row
的部分列,合并结果会展示所有列,不在res
中的列对应的行会显示为NaN。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ListingId 借款金额 借款期限 借款利率 借款成功日期 初始评级 借款类型 是否首标 年龄 性别 0 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 男 1 2707322 5000 3 10.0 2015/6/5 AA 普通 否 35 男 2 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 男 3 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 男 4 2850335 17640 18 16.0 2015/6/18 B 其他 是 28 男 5 3155520 7008 10 11.0 2015/7/12 AA 普通 否 34 男 6 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 男 7 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 男 8 3637812 4000 6 10.5 2015/8/17 AA 其他 是 24 男 9 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 男 0 1693100 3629 6 12.0 2015/1/28 AA 普通 否 31 男 1 1713229 3000 12 12.0 2015/1/30 AA 普通 是 24 男 2 1904026 3629 12 12.0 2015/3/7 AA 普通 否 27 男 3 2158281 3919 12 18.0 2015/4/14 C 普通 否 28 男 4 2257194 14000 12 18.0 2015/4/23 C 普通 否 46 男 5 2272036 40000 6 15.0 2015/4/29 B 电商 是 32 男 6 2315058 3200 3 10.0 2015/4/29 AA 普通 否 25 男 7 2332817 3000 6 12.0 2015/5/6 AA 普通 是 38 男 8 2365175 4260 7 12.0 2015/5/6 AA 普通 否 25 男 9 2370723 11987 12 16.0 2015/5/7 B 其他 否 33 女
重置索引以避免索引重复 在进行行合并时,如果不希望保留原始的索引,可以设置ignore_index=True
,以避免索引重复的问题。
1 2 num = pd.concat([row, res], axis=0 , ignore_index=True ) print (num)
这会创建一个新的DataFrame,其中索引是重新生成的,从0开始,避免了任何索引重复的问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ListingId 借款金额 借款期限 借款利率 借款成功日期 初始评级 借款类型 是否首标 年龄 性别 0 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 男 1 2707322 5000 3 10.0 2015/6/5 AA 普通 否 35 男 2 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 男 3 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 男 4 2850335 17640 18 16.0 2015/6/18 B 其他 是 28 男 5 3155520 7008 10 11.0 2015/7/12 AA 普通 否 34 男 6 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 男 7 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 男 8 3637812 4000 6 10.5 2015/8/17 AA 其他 是 24 男 9 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 男 10 1693100 3629 6 12.0 2015/1/28 AA 普通 否 31 男 11 1713229 3000 12 12.0 2015/1/30 AA 普通 是 24 男 12 1904026 3629 12 12.0 2015/3/7 AA 普通 否 27 男 13 2158281 3919 12 18.0 2015/4/14 C 普通 否 28 男 14 2257194 14000 12 18.0 2015/4/23 C 普通 否 46 男 15 2272036 40000 6 15.0 2015/4/29 B 电商 是 32 男 16 2315058 3200 3 10.0 2015/4/29 AA 普通 否 25 男 17 2332817 3000 6 12.0 2015/5/6 AA 普通 是 38 男 18 2365175 4260 7 12.0 2015/5/6 AA 普通 否 25 男 19 2370723 11987 12 16.0 2015/5/7 B 其他 否 33 女
merge()
在Pandas中,pd.merge()
函数提供了一个强大的方式来合并两个DataFrame,基于一个或多个共同的键。下面,将详细介绍如何使用pd.merge()
进行数据合并,包括基于相同列的简单合并、处理行的选择性读取、以及基于不同列名进行合并。每个案例都会提供代码示例和预期的输出。
示例数据 使用concat()示例中同样的数据
基于共同列合并DataFrame 当两个DataFrame具有至少一个共同的列时,可以使用这个共同列作为合并的基础。以下是如何根据共同列'借款期限'
合并两个DataFrame的示例:
1 2 3 4 5 import pandas as pdnum = pd.merge(row, res, on='借款期限' ) print (num)
在这个示例中,pd.merge()
通过on='借款期限'
参数指定了合并的基础列。这将只保留那些在两个DataFrame中都存在的'借款期限'
值的行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 ListingId_x 借款金额_x 借款期限 借款利率_x 借款成功日期_x 初始评级_x 借款类型_x 是否首标_x 年龄_x \ 0 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 1 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 2 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 3 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 4 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 5 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 6 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 7 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 8 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 9 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 10 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 11 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 12 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 13 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 14 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 15 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 16 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 17 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 18 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 19 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 20 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 21 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 22 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 23 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 24 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 25 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 26 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 27 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 28 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 29 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 30 2707322 5000 3 10.0 2015/6/5 AA 普通 否 35 31 3637812 4000 6 10.5 2015/8/17 AA 其他 是 24 32 3637812 4000 6 10.5 2015/8/17 AA 其他 是 24 33 3637812 4000 6 10.5 2015/8/17 AA 其他 是 24 性别_x ListingId_y 借款金额_y 借款利率_y 借款成功日期_y 初始评级_y 借款类型_y 是否首标_y 年龄_y \ 0 男 1713229 3000 12 2015/1/30 AA 普通 是 24 1 男 1904026 3629 12 2015/3/7 AA 普通 否 27 2 男 2158281 3919 18 2015/4/14 C 普通 否 28 3 男 2257194 14000 18 2015/4/23 C 普通 否 46 4 男 2370723 11987 16 2015/5/7 B 其他 否 33 5 男 1713229 3000 12 2015/1/30 AA 普通 是 24 6 男 1904026 3629 12 2015/3/7 AA 普通 否 27 7 男 2158281 3919 18 2015/4/14 C 普通 否 28 8 男 2257194 14000 18 2015/4/23 C 普通 否 46 9 男 2370723 11987 16 2015/5/7 B 其他 否 33 10 男 1713229 3000 12 2015/1/30 AA 普通 是 24 11 男 1904026 3629 12 2015/3/7 AA 普通 否 27 12 男 2158281 3919 18 2015/4/14 C 普通 否 28 13 男 2257194 14000 18 2015/4/23 C 普通 否 46 14 男 2370723 11987 16 2015/5/7 B 其他 否 33 15 男 1713229 3000 12 2015/1/30 AA 普通 是 24 16 男 1904026 3629 12 2015/3/7 AA 普通 否 27 17 男 2158281 3919 18 2015/4/14 C 普通 否 28 18 男 2257194 14000 18 2015/4/23 C 普通 否 46 19 男 2370723 11987 16 2015/5/7 B 其他 否 33 20 男 1713229 3000 12 2015/1/30 AA 普通 是 24 21 男 1904026 3629 12 2015/3/7 AA 普通 否 27 22 男 2158281 3919 18 2015/4/14 C 普通 否 28 23 男 2257194 14000 18 2015/4/23 C 普通 否 46 24 男 2370723 11987 16 2015/5/7 B 其他 否 33 25 男 1713229 3000 12 2015/1/30 AA 普通 是 24 26 男 1904026 3629 12 2015/3/7 AA 普通 否 27 27 男 2158281 3919 18 2015/4/14 C 普通 否 28 28 男 2257194 14000 18 2015/4/23 C 普通 否 46 29 男 2370723 11987 16 2015/5/7 B 其他 否 33 30 男 2315058 3200 10 2015/4/29 AA 普通 否 25 31 男 1693100 3629 12 2015/1/28 AA 普通 否 31 32 男 2272036 40000 15 2015/4/29 B 电商 是 32 33 男 2332817 3000 12 2015/5/6 AA 普通 是 38 性别_y 0 男 1 男 2 男 3 男 4 女 5 男 6 男 7 男 8 男 9 女 10 男 11 男 12 男 13 男 14 女 15 男 16 男 17 男 18 男 19 女 20 男 21 男 22 男 23 男 24 女 25 男 26 男 27 男 28 男 29 女 30 男 31 男 32 男 33 男
基于不同列名的合并 如果两个DataFrame要合并的列名不同,可以分别使用left_on
和right_on
参数来指定各自的列名:
1 2 num = pd.merge(row, res, left_on='借款期限' , right_on='借款利率' ) print (num)
在这个例子中,尽管row
和res
中要合并的列名不同,但通过left_on
和right_on
参数,我们能够指定如何将两个DataFrame基于对应列的值进行合并。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 ListingId_x 借款金额_x 借款期限_x 借款利率_x 借款成功日期_x 初始评级_x 借款类型_x 是否首标_x 年龄_x \ 0 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 1 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 2 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 3 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 4 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 5 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 6 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 7 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 8 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 9 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 10 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 11 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 12 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 13 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 14 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 15 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 16 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 17 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 18 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 19 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 20 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 21 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 22 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 23 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 24 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 25 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 26 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 27 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 28 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 29 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 30 2850335 17640 18 16.0 2015/6/18 B 其他 是 28 31 2850335 17640 18 16.0 2015/6/18 B 其他 是 28 32 3155520 7008 10 11.0 2015/7/12 AA 普通 否 34 性别_x ListingId_y 借款金额_y 借款期限_y 借款利率_y 借款成功日期_y 初始评级_y 借款类型_y 是否首标_y \ 0 男 1693100 3629 6 12 2015/1/28 AA 普通 否 1 男 1713229 3000 12 12 2015/1/30 AA 普通 是 2 男 1904026 3629 12 12 2015/3/7 AA 普通 否 3 男 2332817 3000 6 12 2015/5/6 AA 普通 是 4 男 2365175 4260 7 12 2015/5/6 AA 普通 否 5 男 1693100 3629 6 12 2015/1/28 AA 普通 否 6 男 1713229 3000 12 12 2015/1/30 AA 普通 是 7 男 1904026 3629 12 12 2015/3/7 AA 普通 否 8 男 2332817 3000 6 12 2015/5/6 AA 普通 是 9 男 2365175 4260 7 12 2015/5/6 AA 普通 否 10 男 1693100 3629 6 12 2015/1/28 AA 普通 否 11 男 1713229 3000 12 12 2015/1/30 AA 普通 是 12 男 1904026 3629 12 12 2015/3/7 AA 普通 否 13 男 2332817 3000 6 12 2015/5/6 AA 普通 是 14 男 2365175 4260 7 12 2015/5/6 AA 普通 否 15 男 1693100 3629 6 12 2015/1/28 AA 普通 否 16 男 1713229 3000 12 12 2015/1/30 AA 普通 是 17 男 1904026 3629 12 12 2015/3/7 AA 普通 否 18 男 2332817 3000 6 12 2015/5/6 AA 普通 是 19 男 2365175 4260 7 12 2015/5/6 AA 普通 否 20 男 1693100 3629 6 12 2015/1/28 AA 普通 否 21 男 1713229 3000 12 12 2015/1/30 AA 普通 是 22 男 1904026 3629 12 12 2015/3/7 AA 普通 否 23 男 2332817 3000 6 12 2015/5/6 AA 普通 是 24 男 2365175 4260 7 12 2015/5/6 AA 普通 否 25 男 1693100 3629 6 12 2015/1/28 AA 普通 否 26 男 1713229 3000 12 12 2015/1/30 AA 普通 是 27 男 1904026 3629 12 12 2015/3/7 AA 普通 否 28 男 2332817 3000 6 12 2015/5/6 AA 普通 是 29 男 2365175 4260 7 12 2015/5/6 AA 普通 否 30 男 2158281 3919 12 18 2015/4/14 C 普通 否 31 男 2257194 14000 12 18 2015/4/23 C 普通 否 32 男 2315058 3200 3 10 2015/4/29 AA 普通 否 年龄_y 性别_y 0 31 男 1 24 男 2 27 男 3 38 男 4 25 男 5 31 男 6 24 男 7 27 男 8 38 男 9 25 男 10 31 男 11 24 男 12 27 男 13 38 男 14 25 男 15 31 男 16 24 男 17 27 男 18 38 男 19 25 男 20 31 男 21 24 男 22 27 男 23 38 男 24 25 男 25 31 男 26 24 男 27 27 男 28 38 男 29 25 男 30 28 男 31 46 男 32 25 男
指定合并方式 pd.merge()
允许通过how
参数来指定合并方式,包括'inner'
(内连接)、'outer'
(外连接)、'left'
(左连接)和'right'
(右连接):
1 2 num = pd.merge(row, res, left_on='借款期限' , right_on='借款利率' , how='inner' ) print (num)
这里,how='inner'
意味着结果中只包含那些两个DataFrame在指定列上都有匹配值的行。不同的how
值可以根据需要选择,以实现不同的合并逻辑。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 ListingId_x 借款金额_x 借款期限_x 借款利率_x 借款成功日期_x 初始评级_x 借款类型_x 是否首标_x 年龄_x \ 0 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 1 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 2 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 3 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 4 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 5 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 6 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 7 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 8 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 9 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 10 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 11 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 12 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 13 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 14 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 15 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 16 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 17 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 18 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 19 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 20 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 21 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 22 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 23 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 24 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 25 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 26 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 27 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 28 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 29 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 30 2850335 17640 18 16.0 2015/6/18 B 其他 是 28 31 2850335 17640 18 16.0 2015/6/18 B 其他 是 28 32 3155520 7008 10 11.0 2015/7/12 AA 普通 否 34 性别_x ListingId_y 借款金额_y 借款期限_y 借款利率_y 借款成功日期_y 初始评级_y 借款类型_y 是否首标_y \ 0 男 1693100 3629 6 12 2015/1/28 AA 普通 否 1 男 1713229 3000 12 12 2015/1/30 AA 普通 是 2 男 1904026 3629 12 12 2015/3/7 AA 普通 否 3 男 2332817 3000 6 12 2015/5/6 AA 普通 是 4 男 2365175 4260 7 12 2015/5/6 AA 普通 否 5 男 1693100 3629 6 12 2015/1/28 AA 普通 否 6 男 1713229 3000 12 12 2015/1/30 AA 普通 是 7 男 1904026 3629 12 12 2015/3/7 AA 普通 否 8 男 2332817 3000 6 12 2015/5/6 AA 普通 是 9 男 2365175 4260 7 12 2015/5/6 AA 普通 否 10 男 1693100 3629 6 12 2015/1/28 AA 普通 否 11 男 1713229 3000 12 12 2015/1/30 AA 普通 是 12 男 1904026 3629 12 12 2015/3/7 AA 普通 否 13 男 2332817 3000 6 12 2015/5/6 AA 普通 是 14 男 2365175 4260 7 12 2015/5/6 AA 普通 否 15 男 1693100 3629 6 12 2015/1/28 AA 普通 否 16 男 1713229 3000 12 12 2015/1/30 AA 普通 是 17 男 1904026 3629 12 12 2015/3/7 AA 普通 否 18 男 2332817 3000 6 12 2015/5/6 AA 普通 是 19 男 2365175 4260 7 12 2015/5/6 AA 普通 否 20 男 1693100 3629 6 12 2015/1/28 AA 普通 否 21 男 1713229 3000 12 12 2015/1/30 AA 普通 是 22 男 1904026 3629 12 12 2015/3/7 AA 普通 否 23 男 2332817 3000 6 12 2015/5/6 AA 普通 是 24 男 2365175 4260 7 12 2015/5/6 AA 普通 否 25 男 1693100 3629 6 12 2015/1/28 AA 普通 否 26 男 1713229 3000 12 12 2015/1/30 AA 普通 是 27 男 1904026 3629 12 12 2015/3/7 AA 普通 否 28 男 2332817 3000 6 12 2015/5/6 AA 普通 是 29 男 2365175 4260 7 12 2015/5/6 AA 普通 否 30 男 2158281 3919 12 18 2015/4/14 C 普通 否 31 男 2257194 14000 12 18 2015/4/23 C 普通 否 32 男 2315058 3200 3 10 2015/4/29 AA 普通 否 年龄_y 性别_y 0 31 男 1 24 男 2 27 男 3 38 男 4 25 男 5 31 男 6 24 男 7 27 男 8 38 男 9 25 男 10 31 男 11 24 男 12 27 男 13 38 男 14 25 男 15 31 男 16 24 男 17 27 男 18 38 男 19 25 男 20 31 男 21 24 男 22 27 男 23 38 男 24 25 男 25 31 男 26 24 男 27 27 男 28 38 男 29 25 男 30 28 男 31 46 男 32 25 男
通过上述示例,可以看到pd.merge()
在Pandas中合并数据时的灵活性和强大功能。这些基础知识使得在进行数据分析和处理时,能够根据实际需求选择合适的合并策略。
join()
在Pandas中,join()
函数是用于将两个或多个DataFrame按照索引合并。这个函数默认执行的是左连接操作,即以调用join()
的DataFrame的索引为基准。不过,可以通过how
参数来指定连接类型,包括left
(左连接)、right
(右连接)、inner
(内连接)和outer
(外连接)。
在尝试使用join()
合并两个DataFrame时,两个DataFrame中存在相同名称的列。join()
方法默认通过索引来合并数据,如果合并的DataFrame中有重叠的列名(即非索引列),则需要指定后缀来区分这些重叠的列,否则会抛出ValueError
。
为了解决这个问题,可以使用lsuffix
和rsuffix
参数来为左右DataFrame中重叠的列名分别添加后缀。这样,即使列名相同,添加了后缀之后也能区分开来。
下面的代码展示了如何使用这些参数来避免错误:
1 2 3 4 5 6 result_right = row.join(res, how='right' , lsuffix='_left' , rsuffix='_right' ) print (result_right)result_outer = row.join(res, how='outer' , lsuffix='_left' , rsuffix='_right' ) print (result_outer)
在这个例子中,lsuffix='_left'
会给左侧DataFrame的重叠列名添加后缀_left
,rsuffix='_right'
会给右侧DataFrame的重叠列名添加后缀_right
。这样,即便原始列名相同,通过添加的后缀也能将它们区分开来,从而避免了错误。
如果目标是基于某些列值而不是索引来合并DataFrame,可能merge()
方法更适合需求,因为它提供了更灵活的列合并选项。
左连接(Left Join) 左连接会保留左侧DataFrame的所有行,即使在右侧DataFrame中没有匹配的索引。如果右侧DataFrame中存在匹配的索引,则相应的列会被添加到结果中。如果不存在,则结果中这些列的值会设置为NaN。
1 2 3 result_left = row.join(res, how='left' , lsuffix='_left' , rsuffix='_right' ) print (result_left)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 ListingId_left 借款金额_left 借款期限_left 借款利率_left 借款成功日期_left 初始评级_left \ 0 2526671 5115 12 12.0 2015/5/23 AA 1 2707322 5000 3 10.0 2015/6/5 AA 2 2722356 3132 12 20.0 2015/6/13 D 3 2828736 3000 12 12.0 2015/6/19 AA 4 2850335 17640 18 16.0 2015/6/18 B 5 3155520 7008 10 11.0 2015/7/12 AA 6 3207478 19928 12 16.0 2015/7/14 B 7 3617672 7000 12 11.5 2015/8/12 AA 8 3637812 4000 6 10.5 2015/8/17 AA 9 3705094 1000 12 11.5 2015/8/21 AA 借款类型_left 是否首标_left 年龄_left 性别_left ListingId_right 借款金额_right \ 0 普通 否 34 男 1693100 3629 1 普通 否 35 男 1713229 3000 2 普通 否 30 男 1904026 3629 3 普通 是 24 男 2158281 3919 4 其他 是 28 男 2257194 14000 5 普通 否 34 男 2272036 40000 6 其他 是 22 男 2315058 3200 7 普通 是 43 男 2332817 3000 8 其他 是 24 男 2365175 4260 9 普通 是 26 男 2370723 11987 借款期限_right 借款利率_right 借款成功日期_right 初始评级_right 借款类型_right 是否首标_right \ 0 6 12 2015/1/28 AA 普通 否 1 12 12 2015/1/30 AA 普通 是 2 12 12 2015/3/7 AA 普通 否 3 12 18 2015/4/14 C 普通 否 4 12 18 2015/4/23 C 普通 否 5 6 15 2015/4/29 B 电商 是 6 3 10 2015/4/29 AA 普通 否 7 6 12 2015/5/6 AA 普通 是 8 7 12 2015/5/6 AA 普通 否 9 12 16 2015/5/7 B 其他 否 年龄_right 性别_right 0 31 男 1 24 男 2 27 男 3 28 男 4 46 男 5 32 男 6 25 男 7 38 男 8 25 男 9 33 女
右连接(Right Join) 右连接与左连接相反,它会保留右侧DataFrame的所有行,即使在左侧DataFrame中没有匹配的索引。
1 2 3 result_right = row.join(res, how='right' , lsuffix='_left' , rsuffix='_right' ) print (result_right)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 ListingId_left 借款金额_left 借款期限_left 借款利率_left 借款成功日期_left 初始评级_left \ 0 2526671 5115 12 12.0 2015/5/23 AA 1 2707322 5000 3 10.0 2015/6/5 AA 2 2722356 3132 12 20.0 2015/6/13 D 3 2828736 3000 12 12.0 2015/6/19 AA 4 2850335 17640 18 16.0 2015/6/18 B 5 3155520 7008 10 11.0 2015/7/12 AA 6 3207478 19928 12 16.0 2015/7/14 B 7 3617672 7000 12 11.5 2015/8/12 AA 8 3637812 4000 6 10.5 2015/8/17 AA 9 3705094 1000 12 11.5 2015/8/21 AA 借款类型_left 是否首标_left 年龄_left 性别_left ListingId_right 借款金额_right \ 0 普通 否 34 男 1693100 3629 1 普通 否 35 男 1713229 3000 2 普通 否 30 男 1904026 3629 3 普通 是 24 男 2158281 3919 4 其他 是 28 男 2257194 14000 5 普通 否 34 男 2272036 40000 6 其他 是 22 男 2315058 3200 7 普通 是 43 男 2332817 3000 8 其他 是 24 男 2365175 4260 9 普通 是 26 男 2370723 11987 借款期限_right 借款利率_right 借款成功日期_right 初始评级_right 借款类型_right 是否首标_right \ 0 6 12 2015/1/28 AA 普通 否 1 12 12 2015/1/30 AA 普通 是 2 12 12 2015/3/7 AA 普通 否 3 12 18 2015/4/14 C 普通 否 4 12 18 2015/4/23 C 普通 否 5 6 15 2015/4/29 B 电商 是 6 3 10 2015/4/29 AA 普通 否 7 6 12 2015/5/6 AA 普通 是 8 7 12 2015/5/6 AA 普通 否 9 12 16 2015/5/7 B 其他 否 年龄_right 性别_right 0 31 男 1 24 男 2 27 男 3 28 男 4 46 男 5 32 男 6 25 男 7 38 男 8 25 男 9 33 女
外连接(Outer Join) 外连接会保留左右两侧DataFrame中的所有行。如果某些行在另一侧没有匹配的索引,则结果DataFrame中这些行的相应列会被设置为NaN。
1 2 3 result_outer = row.join(res, how='outer' , lsuffix='_left' , rsuffix='_right' ) print (result_outer)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 ListingId_left 借款金额_left 借款期限_left 借款利率_left 借款成功日期_left 初始评级_left \ 0 2526671 5115 12 12.0 2015/5/23 AA 1 2707322 5000 3 10.0 2015/6/5 AA 2 2722356 3132 12 20.0 2015/6/13 D 3 2828736 3000 12 12.0 2015/6/19 AA 4 2850335 17640 18 16.0 2015/6/18 B 5 3155520 7008 10 11.0 2015/7/12 AA 6 3207478 19928 12 16.0 2015/7/14 B 7 3617672 7000 12 11.5 2015/8/12 AA 8 3637812 4000 6 10.5 2015/8/17 AA 9 3705094 1000 12 11.5 2015/8/21 AA 借款类型_left 是否首标_left 年龄_left 性别_left ListingId_right 借款金额_right \ 0 普通 否 34 男 1693100 3629 1 普通 否 35 男 1713229 3000 2 普通 否 30 男 1904026 3629 3 普通 是 24 男 2158281 3919 4 其他 是 28 男 2257194 14000 5 普通 否 34 男 2272036 40000 6 其他 是 22 男 2315058 3200 7 普通 是 43 男 2332817 3000 8 其他 是 24 男 2365175 4260 9 普通 是 26 男 2370723 11987 借款期限_right 借款利率_right 借款成功日期_right 初始评级_right 借款类型_right 是否首标_right \ 0 6 12 2015/1/28 AA 普通 否 1 12 12 2015/1/30 AA 普通 是 2 12 12 2015/3/7 AA 普通 否 3 12 18 2015/4/14 C 普通 否 4 12 18 2015/4/23 C 普通 否 5 6 15 2015/4/29 B 电商 是 6 3 10 2015/4/29 AA 普通 否 7 6 12 2015/5/6 AA 普通 是 8 7 12 2015/5/6 AA 普通 否 9 12 16 2015/5/7 B 其他 否 年龄_right 性别_right 0 31 男 1 24 男 2 27 男 3 28 男 4 46 男 5 32 男 6 25 男 7 38 男 8 25 男 9 33 女
内连接(Inner Join) 内连接只保留两个DataFrame中都有匹配的行。如果某行在另一侧没有匹配的索引,则这行不会出现在结果DataFrame中。
使用示例 在的例子中,使用join()
可能不会直接给出期望的结果,因为join()
默认是按索引进行合并的。如果DataFrame没有设置索引或者两个DataFrame的索引并不完全匹配,那么合并的结果可能不会是期望的。在这种情况下,使用merge()
函数可能更为合适,因为它允许指定合并的列。
不过,如果仍想使用join()
并基于列进行合并,可能需要先将某个列设置为索引,然后再进行连接操作。这里给出的代码示例直接使用join()
,假设已经有了适当的索引设置。
1 2 3 4 5 6 df = pd.read_csv('./LCIS.csv' , nrows=5 , usecols=range (3 ,6 )) res = pd.DataFrame(df) print (row.join(res, how='right' , lsuffix='_left' , rsuffix='_right' ))print (row.join(res, how='outer' , lsuffix='_left' , rsuffix='_right' ))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 ListingId 借款金额 借款期限 借款利率_left 借款成功日期_left 初始评级_left 借款类型 是否首标 年龄 性别 \ 0 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 男 1 2707322 5000 3 10.0 2015/6/5 AA 普通 否 35 男 2 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 男 3 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 男 4 2850335 17640 18 16.0 2015/6/18 B 其他 是 28 男 借款利率_right 借款成功日期_right 初始评级_right 0 12 2015/1/28 AA 1 12 2015/1/30 AA 2 12 2015/3/7 AA 3 18 2015/4/14 C 4 18 2015/4/23 C ListingId 借款金额 借款期限 借款利率_left 借款成功日期_left 初始评级_left 借款类型 是否首标 年龄 性别 \ 0 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 男 1 2707322 5000 3 10.0 2015/6/5 AA 普通 否 35 男 2 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 男 3 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 男 4 2850335 17640 18 16.0 2015/6/18 B 其他 是 28 男 5 3155520 7008 10 11.0 2015/7/12 AA 普通 否 34 男 6 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 男 7 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 男 8 3637812 4000 6 10.5 2015/8/17 AA 其他 是 24 男 9 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 男 借款利率_right 借款成功日期_right 初始评级_right 0 12.0 2015/1/28 AA 1 12.0 2015/1/30 AA 2 12.0 2015/3/7 AA 3 18.0 2015/4/14 C 4 18.0 2015/4/23 C 5 NaN NaN NaN 6 NaN NaN NaN 7 NaN NaN NaN 8 NaN NaN NaN 9 NaN NaN NaN
如果DataFrame没有公共列作为索引,可能需要先使用.set_index()
方法来设置索引。
数据删除 当处理数据集时,删除不需要的列或行是常见的数据清理步骤。在Pandas中,可以通过del
语句或DataFrame.drop
方法来实现。下面是如何使用这两种方法来删除数据的详细说明和示例:
使用del
语句删除列 del
语句是Python的一个内置功能,它可以从DataFrame中直接删除指定的列。使用del
语句时,更改是立即生效的,并且直接在原DataFrame上进行,不返回新的DataFrame。
示例代码:
这行代码会从row
DataFrame中删除名为'ListingId'
的列。
使用drop
方法删除数据 drop
方法在Pandas中更加灵活,可以用于删除行或列,且可以控制是直接在原DataFrame上进行修改还是返回一个新的DataFrame。
删除行: 1 2 print (row.drop(0 )) print (row.drop([1 , 2 ], inplace=False ))
删除列: 1 print (row.drop(['ListingId' ], axis=1 ))
在使用drop
方法时,重要的参数包括:
labels
: 指定要删除的行标签或列名称。
axis
: 通过设置0
或1
指定删除行或列。0
代表行,1
代表列。
inplace
: 通过设置True
或False
指定是否在原地修改DataFrame。True
表示在原DataFrame上修改,False
(默认值)表示返回一个新的DataFrame,原DataFrame不变。
Pandas数据清洗 在数据分析过程中,经常会遇到包含重复行的数据集,这可能会对分析结果产生不利影响。Pandas提供了方便的工具来帮助识别和删除这些重复的数据。下面是如何在Pandas中清洗重复数据的详细说明和示例:
清洗重复数据 读取数据 首先,我们通过读取一个CSV文件来创建一个DataFrame,作为处理重复数据的示例:
1 2 3 4 5 import pandas as pddf = pd.read_csv('./LCIS.csv' , nrows=50 ) row = pd.DataFrame(df)
检查重复行 使用DataFrame.duplicated()
方法可以检查DataFrame中的重复行。此方法返回一个布尔系列,其中True
表示对应的行是重复的,而False
表示行是唯一的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 0 False 1 False 2 False 3 False 4 False 5 False 6 False 7 False 8 False 9 False 10 False 11 False 12 False 13 False 14 False 15 False 16 False 17 False 18 False 19 False 20 False 21 False 22 False 23 False 24 False 25 False 26 False 27 False 28 False 29 False 30 False 31 False 32 False 33 False 34 False 35 False 36 False 37 False 38 False 39 False 40 False 41 False 42 False 43 False 44 False 45 False 46 False 47 False 48 False 49 False dtype: bool
此外,还可以通过对一个简单的DataFrame进行操作来理解重复值的检查:
1 2 3 4 5 6 7 data = {'A' : [1 , 1 , 2 , 3 , 3 ], 'B' : ['a' , 'a' , 'b' , 'c' , 'c' ]} df = pd.DataFrame(data) df_count = df.duplicated().sum () print (df_count)
删除重复行 使用DataFrame.drop_duplicates()
方法可以删除DataFrame中的重复行。如果设置inplace=True
,则会在原地修改DataFrame,而不是返回一个新的DataFrame。
1 2 3 4 5 6 7 row.drop_duplicates(inplace=True ) print (row)print ("=============================================" )df.drop_duplicates(inplace=True ) print (df)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 ListingId 借款金额 借款期限 借款利率 借款成功日期 初始评级 借款类型 是否首标 年龄 性别 ... \ 0 1693100 3629 6 12.0 2015/1/28 AA 普通 否 31 男 ... 1 1713229 3000 12 12.0 2015/1/30 AA 普通 是 24 男 ... 2 1904026 3629 12 12.0 2015/3/7 AA 普通 否 27 男 ... 3 2158281 3919 12 18.0 2015/4/14 C 普通 否 28 男 ... 4 2257194 14000 12 18.0 2015/4/23 C 普通 否 46 男 ... 5 2272036 40000 6 15.0 2015/4/29 B 电商 是 32 男 ... 6 2315058 3200 3 10.0 2015/4/29 AA 普通 否 25 男 ... 7 2332817 3000 6 12.0 2015/5/6 AA 普通 是 38 男 ... 8 2365175 4260 7 12.0 2015/5/6 AA 普通 否 25 男 ... 9 2370723 11987 12 16.0 2015/5/7 B 其他 否 33 女 ... 10 2526671 5115 12 12.0 2015/5/23 AA 普通 否 34 男 ... 11 2707322 5000 3 10.0 2015/6/5 AA 普通 否 35 男 ... 12 2722356 3132 12 20.0 2015/6/13 D 普通 否 30 男 ... 13 2828736 3000 12 12.0 2015/6/19 AA 普通 是 24 男 ... 14 2850335 17640 18 16.0 2015/6/18 B 其他 是 28 男 ... 15 3155520 7008 10 11.0 2015/7/12 AA 普通 否 34 男 ... 16 3207478 19928 12 16.0 2015/7/14 B 其他 是 22 男 ... 17 3617672 7000 12 11.5 2015/8/12 AA 普通 是 43 男 ... 18 3637812 4000 6 10.5 2015/8/17 AA 其他 是 24 男 ... 19 3705094 1000 12 11.5 2015/8/21 AA 普通 是 26 男 ... 20 3846919 5719 6 18.0 2015/8/26 C 普通 否 34 男 ... 21 7285364 8000 12 20.0 2016/1/6 C 普通 否 26 男 ... 22 7447346 4650 12 22.0 2016/1/9 C 普通 否 29 男 ... 23 7760072 9000 12 20.0 2016/1/21 C 其他 是 37 男 ... 24 7777242 9000 12 20.0 2016/1/21 C 普通 是 29 女 ... 25 7966976 8500 12 20.0 2016/1/24 C 普通 否 43 男 ... 26 8148541 13500 12 20.0 2016/1/28 C 普通 否 32 女 ... 27 8260540 6500 12 20.0 2016/1/30 C 普通 否 26 男 ... 28 8297477 6500 12 22.0 2016/1/31 C 普通 否 35 男 ... 29 8359807 8000 12 18.0 2016/2/3 B 普通 是 27 男 ... 30 8377465 11500 12 20.0 2016/2/2 C 普通 否 46 男 ... 31 8883343 25000 12 20.0 2016/2/23 C 普通 否 27 男 ... 32 8978256 8000 12 18.0 2016/2/25 B APP闪电 是 23 男 ... 33 8987694 5000 6 20.0 2016/2/26 C 普通 否 42 男 ... 34 9045950 4000 6 18.0 2016/2/28 B APP闪电 是 21 男 ... 35 9182372 8000 12 18.0 2016/3/2 B APP闪电 是 46 男 ... 36 9482974 3300 6 20.0 2016/3/11 C 普通 否 36 女 ... 37 9581580 7000 12 18.0 2016/3/12 B APP闪电 是 23 女 ... 38 9597362 1000 6 10.0 2016/3/17 AA 普通 是 23 男 ... 39 9601032 3000 12 18.0 2016/3/13 B APP闪电 是 25 女 ... 40 9602590 1200 12 12.0 2016/3/13 AA APP闪电 是 24 男 ... 41 9809712 4000 12 16.0 2016/3/20 A APP闪电 是 21 女 ... 42 9993691 3000 12 18.0 2016/3/26 B APP闪电 是 26 男 ... 43 10240655 2725 12 18.0 2016/4/4 B 普通 否 32 男 ... 44 10259916 1500 12 20.0 2016/3/29 C APP闪电 是 22 女 ... 45 10410378 4497 6 18.0 2016/4/1 B 其他 否 31 女 ... 46 10604020 2055 6 18.0 2016/4/6 B 普通 否 25 男 ... 47 10646264 2000 12 12.0 2016/4/7 AA APP闪电 是 25 女 ... 48 10829990 5782 12 20.0 2016/4/12 C 其他 否 32 男 ... 49 11055233 4139 12 22.0 2016/4/17 C 普通 否 36 男 ... 待还利息 标当前逾期天数 标当前状态 上次还款日期 上次还款本金 上次还款利息 下次计划还款日期 下次计划还款本金 \ 0 0.00 0 已还清 2015/7/28 34.20 0.30 NaN NaN 1 0.00 0 已还清 2015/10/19 173.39 1.05 NaN NaN 2 0.00 0 已还清 2016/3/6 44.04 0.38 NaN NaN 3 0.00 0 已还清 2015/5/19 92.34 0.22 NaN NaN 4 9.92 589 逾期中 NaN NaN NaN 2015/5/23 7.66 5 0.00 0 已还清 2015/10/27 35.43 0.42 NaN NaN 6 0.00 0 已还清 2015/7/17 134.45 1.11 NaN NaN 7 0.00 0 已还清 2015/11/6 8.74 0.05 NaN NaN 8 0.00 0 已还清 2015/8/5 29.59 0.00 NaN NaN 9 0.00 0 已还清 2016/1/22 35.16 0.18 NaN NaN 10 0.00 0 已还清 2016/5/22 3.58 0.00 NaN NaN 11 0.00 0 已还清 2015/9/5 63.20 0.51 NaN NaN 12 0.00 0 已还清 2015/7/20 7.31 0.00 NaN NaN 13 0.00 0 已还清 2016/4/21 52.54 0.01 NaN NaN 14 0.25 0 正常还款中 2016/12/15 1.14 0.11 2017/1/18 1.16 15 0.00 0 已还清 2016/5/12 52.11 0.44 NaN NaN 16 0.00 0 已还清 2016/12/13 26.74 0.28 NaN NaN 17 0.00 0 已还清 2015/10/18 43.94 0.36 NaN NaN 18 0.00 0 已还清 2015/9/14 300.00 2.45 NaN NaN 19 0.00 0 已还清 2016/8/20 13.22 0.07 NaN NaN 20 0.00 0 已还清 2015/11/15 33.84 0.32 NaN NaN 21 2.02 179 逾期中 2016/6/6 4.05 0.58 2016/7/6 4.12 22 0.00 0 已还清 2016/11/25 9.14 0.05 NaN NaN 23 0.02 0 正常还款中 2016/12/20 4.48 0.15 2017/1/21 4.61 24 0.02 0 正常还款中 2016/12/20 4.48 0.15 2017/1/21 4.61 25 0.02 0 正常还款中 2016/12/24 4.48 0.15 2017/1/24 4.61 26 0.00 0 已还清 2016/8/26 22.08 0.00 NaN NaN 27 0.17 2 逾期中 2016/11/30 4.40 0.23 2016/12/30 4.48 28 0.04 0 正常还款中 2016/12/31 4.51 0.16 2017/1/31 4.63 29 0.04 0 正常还款中 2016/12/3 1.40 0.06 2017/1/3 1.42 30 0.02 0 正常还款中 2016/12/18 4.48 0.15 2017/2/2 4.61 31 0.00 0 已还清 2016/12/23 4.61 0.02 NaN NaN 32 0.14 0 正常还款中 2016/12/30 4.38 0.20 2017/1/25 4.44 33 0.00 0 已还清 2016/6/29 17.24 0.00 NaN NaN 34 0.00 0 已还清 2016/8/23 8.68 0.09 NaN NaN 35 0.34 0 正常还款中 2016/12/1 4.31 0.27 2017/1/2 4.38 36 0.00 0 已还清 2016/9/3 8.71 0.11 NaN NaN 37 0.34 0 正常还款中 2016/12/10 4.31 0.27 2017/1/12 4.38 38 0.00 0 已还清 2016/9/17 85.08 0.70 NaN NaN 39 0.34 0 正常还款中 2016/12/11 4.31 0.27 2017/1/13 4.38 40 2.55 0 正常还款中 2016/12/14 42.68 1.74 2017/1/13 43.11 41 0.30 0 正常还款中 2016/12/23 4.30 0.23 2017/1/20 4.35 42 0.00 0 已还清 2016/12/23 4.58 0.00 NaN NaN 43 0.14 0 正常还款中 2016/12/28 4.38 0.20 2017/3/4 4.44 44 0.40 0 正常还款中 2016/12/29 4.33 0.30 2017/1/29 4.40 45 0.00 0 已还清 2016/8/29 8.68 0.00 NaN NaN 46 0.00 0 已还清 2016/8/28 17.19 0.16 NaN NaN 47 1.66 0 正常还款中 2016/12/8 16.90 0.86 2017/1/7 0.00 48 0.81 0 正常还款中 2016/12/10 4.94 0.43 2017/1/12 5.02 49 0.00 0 已还清 2016/10/24 26.38 0.09 NaN NaN 下次计划还款利息 recorddate 0 NaN 2016/12/31 1 NaN 2016/12/31 2 NaN 2016/12/31 3 NaN 2016/12/31 4 1.50 2016/12/31 5 NaN 2016/12/31 6 NaN 2016/12/31 7 NaN 2016/12/31 8 NaN 2016/12/31 9 NaN 2016/12/31 10 NaN 2016/12/31 11 NaN 2016/12/31 12 NaN 2016/12/31 13 NaN 2016/12/31 14 0.09 2016/12/31 15 NaN 2016/12/31 16 NaN 2016/12/31 17 NaN 2016/12/31 18 NaN 2016/12/31 19 NaN 2016/12/31 20 NaN 2016/12/31 21 0.51 2016/12/31 22 NaN 2016/12/31 23 0.02 2016/12/31 24 0.02 2016/12/31 25 0.02 2016/12/31 26 NaN 2016/12/31 27 0.15 2016/12/31 28 0.04 2016/12/31 29 0.04 2016/12/31 30 0.02 2016/12/31 31 NaN 2016/12/31 32 0.14 2016/12/31 33 NaN 2016/12/31 34 NaN 2016/12/31 35 0.20 2016/12/31 36 NaN 2016/12/31 37 0.20 2016/12/31 38 NaN 2016/12/31 39 0.20 2016/12/31 40 1.31 2016/12/31 41 0.18 2016/12/31 42 NaN 2016/12/31 43 0.14 2016/12/31 44 0.23 2016/12/31 45 NaN 2016/12/31 46 NaN 2016/12/31 47 0.00 2016/12/31 48 0.35 2016/12/31 49 NaN 2016/12/31 [50 rows x 37 columns] ============================================= A B 0 1 a 2 2 b 3 3 c
通过这种方式,可以有效地清理数据集中的重复项,确保进行数据分析时数据的准确性和可靠性。在实际的数据处理中,根据数据的具体情况和需求,合理地使用这些方法可以大大提高数据分析的质量和效率。
清洗空值 在数据处理和分析中,处理缺失值是一个重要的步骤,因为缺失值可能会影响数据分析的结果。Pandas 提供了多种方法来处理 DataFrame 中的缺失值。下面我们将详细探讨如何统计空值,计算缺失率,删除含有空值的行或列,以及填充空值的不同方法。
统计空值和计算缺失率 统计空值数量 1 2 3 4 5 6 7 8 9 import pandas as pddf = pd.read_csv('./LCIS.csv' , nrows=50 ) row = pd.DataFrame(df) res = row.isnull().sum () print (res)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 ListingId 0 借款金额 0 借款期限 0 借款利率 0 借款成功日期 0 初始评级 0 借款类型 0 是否首标 0 年龄 0 性别 0 手机认证 0 户口认证 0 视频认证 0 学历认证 0 征信认证 0 淘宝认证 0 历史成功借款次数 0 历史成功借款金额 0 总待还本金 0 历史正常还款期数 0 历史逾期还款期数 0 我的投资金额 0 当前到期期数 0 当前还款期数 0 已还本金 0 已还利息 0 待还本金 0 待还利息 0 标当前逾期天数 0 标当前状态 0 上次还款日期 1 上次还款本金 1 上次还款利息 1 下次计划还款日期 30 下次计划还款本金 30 下次计划还款利息 30 recorddate 0 dtype: int64
计算缺失率
1 2 3 4 res = round ((row.isnull().sum () / len (row) * 100 ), 2 ) row = pd.DataFrame({'列名' : res.index, '缺失值占比' : res.values}) print (row)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 列名 缺失值占比 0 ListingId 0.0 1 借款金额 0.0 2 借款期限 0.0 3 借款利率 0.0 4 借款成功日期 0.0 5 初始评级 0.0 6 借款类型 0.0 7 是否首标 0.0 8 年龄 0.0 9 性别 0.0 10 手机认证 0.0 11 户口认证 0.0 12 视频认证 0.0 13 学历认证 0.0 14 征信认证 0.0 15 淘宝认证 0.0 16 历史成功借款次数 0.0 17 历史成功借款金额 0.0 18 总待还本金 0.0 19 历史正常还款期数 0.0 20 历史逾期还款期数 0.0 21 我的投资金额 0.0 22 当前到期期数 0.0 23 当前还款期数 0.0 24 已还本金 0.0 25 已还利息 0.0 26 待还本金 0.0 27 待还利息 0.0 28 标当前逾期天数 0.0 29 标当前状态 0.0 30 上次还款日期 2.0 31 上次还款本金 2.0 32 上次还款利息 2.0 33 下次计划还款日期 60.0 34 下次计划还款本金 60.0 35 下次计划还款利息 60.0 36 recorddate 0.0
1 2 3 4 5 6 7 8 9 10 df = pd.read_csv('./LCIS.csv' ) rows_with_na = df.isnull().any (axis=1 ).sum () total_missing_rate = round ((rows_with_na / len (df) * 100 ), 2 ) print (f"总缺失率: {total_missing_rate} %" )
删除含有空值的行或列 使用 dropna()
方法可以根据不同的需求删除含有空值的行或列。
DataFrame.dropna
参数说明:
axis
: 控制删除含有缺失值的行或列。默认值为 0
,意味着删除任何含有缺失值的行。如果设置为 1
,则删除任何含有缺失值的列。
how
: 定义了行或列被删除的条件。默认为 'any'
,表示如果行或列中存在任何缺失值,就将其删除。如果设置为 'all'
,则只有当行或列中的所有值都是缺失值时,才删除该行或列。
thresh
: 指定一个行或列中非缺失值的最小数量,只有当非缺失值的数量达到这个阈值时,该行或列才会被保留。
subset
: 用于指定一个列的子集来检查缺失值。这可以是单个列名,或者是多个列名组成的列表。只有在这个子集中检查到缺失值时,相应的行或列才会根据how
参数的设置被删除。
inplace
: 用于指定是否在原地修改DataFrame。如果设置为True
,则原地修改DataFrame并返回None
;如果设置为False
(默认),则返回修改后的新DataFrame,原DataFrame不变。
删除含有任何空值的行:
1 row.dropna(axis=0 , inplace=True )
1 row.dropna(axis=1 , inplace=True )
填充空值 在很多情况下,直接删除含有空值的数据可能会导致信息的大量丢失,特别是在数据量不是很大的情况下。此时,填充空值成为了一种更好的选择。
1 2 row.fillna(0 , inplace=True )
1 2 row['下次计划还款日期' ].fillna(1234 , inplace=True )
1 2 3 4 5 6 7 8 9 10 11 mean_val = row['下次计划还款利息' ].mean() row['下次计划还款利息' ].fillna(mean_val, inplace=True ) median_val = row['下次计划还款利息' ].median() row['下次计划还款利息' ].fillna(median_val, inplace=True ) mode_val = row['下次计划还款利息' ].mode()[0 ] row['下次计划还款利息' ].fillna(mode_val, inplace=True )
错误数据清洗 在数据处理和分析中,清洗数据是一项基础而重要的任务,用于修正或删除数据集中的错误或不一致的数据。Pandas 是一个强大的 Python 数据分析库,它提供了多种方法来清洗错误数据。
替换错误数据 直接替换特定错误数据 如果已知特定数据项错误,可以直接替换它。例如,如果我们知道某个人的年龄被错误地录入为12345,而正确的年龄应为30,可以直接修改这个值:
1 2 3 4 5 6 7 8 9 10 11 12 13 import pandas as pdperson = { "name" : ['Google' , 'Runoob' , 'Taobao' ], "age" : [50 , 40 , 12345 ] } df = pd.DataFrame(person) df.loc[2 , 'age' ] = 30 print (df)
基于条件的批量替换 在某些情况下,我们可能需要根据条件批量替换数据。例如,将所有大于120岁的年龄替换为120岁:
1 2 3 4 5 6 7 8 9 10 11 12 import pandas as pdperson = { "name" : ['Google' , 'Runoob' , 'Taobao' ], "age" : [50 , 200 , 12345 ] } df = pd.DataFrame(person) df.loc[df['age' ] > 120 , 'age' ] = 120 print (df)
删除错误数据 有时,与其修正错误的数据,不如直接将其删除。例如,删除年龄大于120岁的记录:
1 2 3 4 5 6 7 8 9 10 11 12 import pandas as pdperson = { "name" : ['Google' , 'Runoob' , 'Taobao' ], "age" : [50 , 40 , 12345 ] } df = pd.DataFrame(person) df = df[df['age' ] <= 120 ] print (df)
数据格式错误处理 假设我们有一个包含日期和持续时间的数据集,但日期的格式不统一,这可能会导致分析时出现问题。以下是如何使用 Pandas 来解决这一问题的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import pandas as pddata = { "Date" : ['2020/12/01' , '2020/12/02' , '20201226' ], "Duration" : [50 , 40 , 45 ] } df = pd.DataFrame(data, index=["day1" , "day2" , "day3" ]) df['Date' ] = pd.to_datetime(df['Date' ], errors='coerce' , format ='%Y/%m/%d' ) print (df)
代码解析
导入 Pandas 库 :首先,我们需要导入 Pandas 库,这是进行数据分析和数据清洗的基础。
创建 DataFrame :我们通过传递一个包含数据的字典(包括不一致的日期格式)来创建一个 DataFrame
。这个 DataFrame
包括一个日期列和一个持续时间列。
转换日期格式 :使用 pd.to_datetime()
方法将日期列转换为统一的 datetime 格式。这个方法非常强大,能够自动识别和转换多种日期格式。如果存在无法识别的格式,errors='coerce'
参数会将这些无法转换的日期替换为 NaT
(时间戳数据的缺失值)。format='%Y/%m/%d'
参数是尝试按照这种格式解析日期,但不一定所有日期都能完全匹配此格式,故 errors='coerce'
在这里起着兜底的作用。
扩展和改进
处理转换错误 :在转换过程中,如果存在无法识别的日期格式,我们可以通过 errors='coerce'
参数来处理这些错误,将它们转换为 NaT
,然后根据需要进行进一步处理,比如填充缺失值或者删除包含缺失值的行。
格式化输出 :在完成日期格式的统一后,我们还可以根据需要对日期进行格式化,比如将所有日期转换为特定的字符串格式。
其他数据清洗任务 :除了解决日期格式问题外,数据清洗可能还包括诸如删除重复值、处理缺失值、数据类型转换等任务。Pandas 提供了丰富的函数和方法来处理这些问题,比如 drop_duplicates()
、fillna()
或 replace()
方法。
数据统计和运算是数据分析的基础,它涉及到对数据集进行概括性描述和数学计算的过程。Pandas 是一个强大的 Python 数据分析库,提供了一系列方便的数据统计和运算工具,帮助我们快速对数据进行处理和分析。以下是一些使用 Pandas 进行数据统计和运算的常用方法及其应用示例。
数据统计和运算 数据统计和运算是数据分析的基础,它涉及到对数据集进行概括性描述和数学计算的过程。Pandas 是一个强大的 Python 数据分析库,提供了一系列方便的数据统计和运算工具,帮助我们快速对数据进行处理和分析。以下是一些使用 Pandas 进行数据统计和运算的常用方法及其应用示例。
最大值和最小值:max()
和 min()
1 2 3 4 5 6 7 8 9 10 11 12 13 import pandas as pddf = pd.read_csv("./LCIS.csv" ) max_value = df['借款金额' ].max () min_value = df['借款金额' ].min () print ("最大借款金额:" , max_value)print ("最小借款金额:" , min_value)
这段代码展示了如何读取一个 CSV 文件,并计算某一列(例如“借款金额”)的最大值和最小值。
非缺失值的数量:count()
df.count(axis=0, level=None, numeric_only=False)
axis
:指定计算的方向,0 表示按列计算,1 表示按行计算,默认为 0。
level
:用于 MultiIndex 的级别,在多层索引 DataFrame 中指定要计算的级别。
numeric_only
:布尔值,表示是否只计算数值型列(int、float)的非缺失值,默认为 False,表示计算所有列的非缺失值数量。
1 2 3 4 5 6 7 8 9 10 11 12 import pandas as pddf = pd.read_csv("./LCIS.csv" ) column_non_missing_count = df.count() row_non_missing_count = df.count(axis=1 ) print (column_non_missing_count)print (row_non_missing_count)
此代码展示了如何计算 DataFrame 中每列或每行的非缺失值(非 NaN 值)的数量。可以通过设置 axis
参数为 0(默认)计算每列的非缺失值数量,或设置为 1 计算每行的非缺失值数量。
求和与累加:sum()
和 cumsum()
1 2 3 4 5 6 7 total = df['借款金额' ].sum () print ("借款金额总和:" , total)df['累计借款金额' ] = df['借款金额' ].cumsum() print (df)
这部分代码用于计算特定列的总和(sum()
)和累加值(cumsum()
)。cumsum()
方法在原有数据的基础上添加了一个累加列,显示到当前行为止的累计总和。
排序:sort_values()
和 sort_index()
按列值排序 1 2 3 4 5 df.sort_values('借款金额' , inplace=True ) df.sort_values(['借款金额' , '年龄' ], ascending=[True , False ], inplace=True )
这些例子展示了如何按照一个或多个列的值对 DataFrame 进行排序。可以通过 ascending
参数控制排序的方向(升序或降序)。
按索引排序 1 2 df.sort_index(inplace=True )
如果需要根据行索引进行排序,可以使用 sort_index()
方法。这在重置数据顺序时特别有用。
扩展
计算缺失值 :利用 count()
方法的结果可以间接计算出某列或整个 DataFrame 的缺失值数量。例如,DataFrame 总行数减去 count()
方法返回的非缺失值数量即为缺失值数量。
设置列名 :当从函数返回一个 Series 或需要更改 DataFrame 的列名时,可以直接通过修改 columns
属性或者在创建 DataFrame 时指定列名。
读取部分数据 :对于大型数据集,可以使用 pd.read_csv()
函数的 nrows
参数仅读取前 N 行数据,有助于快速测试代码或减少内存消耗。
数据分组和聚合 df.groupby(column_name) groupby()
方法是用来对数据进行分组的,特别是当你想要按照某个(或某些)列的值对整个数据集进行分组时。分组后,可以对每个分组应用聚合函数,比如求和、平均、最大值和最小值等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 age_group_count = df.groupby('年龄' ).count() print (age_group_count)age_group_loan_sum = df.groupby('年龄' )['借款金额' ].sum () print (age_group_loan_sum)age_group_loan_max = df.groupby('年龄' )['借款金额' ].max () age_group_loan_min = df.groupby('年龄' )['借款金额' ].min () age_group_loan_mean = df.groupby('年龄' )['借款金额' ].mean() print (age_group_loan_max)print (age_group_loan_min)print (age_group_loan_mean)gender_group_loan_max = df.groupby('性别' )['借款金额' ].max () gender_group_loan_min = df.groupby('性别' )['借款金额' ].min () gender_group_loan_mean = df.groupby('性别' )['借款金额' ].mean() print (gender_group_loan_max)print (gender_group_loan_min)print (gender_group_loan_mean)
df.aggregate(function_name) aggregate()
方法允许你对整个 DataFrame 或某些选定的列应用一个或多个聚合函数。
1 2 3 4 5 6 7 agg_results = df.aggregate(['sum' , 'mean' ]) print (agg_results) agg_specific = df.aggregate({'借款金额' : 'sum' , '年龄' : 'mean' }) print (agg_specific)
如果数据集中包含非数值类型(如字符串),直接应用 sum
或 mean
会导致错误。为了避免这种情况,你应该指定要应用聚合函数的列,或者通过 numeric_only=True
参数来排除非数值列。
df.pivot_table(values, index, columns, aggfunc) pivot_table()
方法是用来创建透视表的,这在你想要对数据进行多维度的分组聚合时特别有用。
1 2 3 gender_loan_pivot_table = df.pivot_table(values='借款金额' , index='性别' , aggfunc='sum' ) print (gender_loan_pivot_table)
在透视表中,values
参数是你想要聚合的列,index
参数是你想要作为行索引的列,columns
参数(可选)是你想要作为列索引的列,aggfunc
是定义聚合函数的参数。
这些方法不仅可以帮助你从数据集中提取有意义的统计信息,还可以根据你的特定需求进行高度定制化的数据处理和分析。通过使用这些工具,你可以轻松地对数据进行分组和聚合,从而提取出关键的洞见。
案例 数据导入与演示 1 2 3 4 5 6 7 8 9 import pandas as pddf = pd.read_csv('./LCIS.csv' ) pd.set_option('display.max_columns' , None ) print (df)
ListingId 借款金额 借款期限 借款利率 借款成功日期 初始评级 借款类型 是否首标 年龄 性别 手机认证 \
0 1693100 3629 6 12.0 2015/1/28 AA 普通 否 31 男 成功认证
1 1713229 3000 12 12.0 2015/1/30 AA 普通 是 24 男 成功认证
2 1904026 3629 12 12.0 2015/3/7 AA 普通 否 27 男 成功认证
3 2158281 3919 12 18.0 2015/4/14 C 普通 否 28 男 成功认证
4 2257194 14000 12 18.0 2015/4/23 C 普通 否 46 男 成功认证
... ... ... ... ... ... ... ... ... .. .. ...
292534 29087298 7193 12 22.0 2016/12/29 C 普通 否 48 男 成功认证
292535 29995173 3241 12 22.0 2017/1/5 C 其他 否 25 女 成功认证
292536 30355195 3004 12 22.0 2017/1/8 C 其他 否 28 男 未成功认证
292537 30649717 2082 12 22.0 2017/1/11 C 普通 否 52 男 成功认证
292538 31620657 10000 12 22.0 2017/1/20 D 普通 是 24 女 未成功认证
户口认证 视频认证 学历认证 征信认证 淘宝认证 历史成功借款次数 历史成功借款金额 总待还本金 \
0 未成功认证 未成功认证 未成功认证 未成功认证 未成功认证 1.0 3000.0 1313.46
1 未成功认证 未成功认证 未成功认证 未成功认证 未成功认证 0.0 0.0 0.00
2 未成功认证 未成功认证 未成功认证 未成功认证 未成功认证 1.0 3000.0 878.58
3 成功认证 未成功认证 未成功认证 未成功认证 未成功认证 4.0 13800.0 6523.11
4 未成功认证 未成功认证 未成功认证 未成功认证 未成功认证 11.0 54840.0 11491.04
... ... ... ... ... ... ... ... ...
292534 未成功认证 未成功认证 未成功认证 未成功认证 未成功认证 1.0 3500.0 306.54
292535 未成功认证 未成功认证 成功认证 未成功认证 未成功认证 1.0 5000.0 1758.28
292536 未成功认证 未成功认证 未成功认证 未成功认证 未成功认证 1.0 2200.0 1495.67
292537 未成功认证 未成功认证 未成功认证 未成功认证 未成功认证 6.0 22064.0 5747.77
292538 未成功认证 未成功认证 成功认证 未成功认证 未成功认证 0.0 0.0 0.00
历史正常还款期数 历史逾期还款期数 我的投资金额 当前到期期数 当前还款期数 已还本金 已还利息 待还本金 \
0 2 2 200 6 6 200.00 7.00 0.00
1 0 0 500 12 9 500.00 29.80 0.00
2 5 0 500 12 12 500.00 33.04 0.00
3 25 0 100 12 2 100.00 1.72 0.00
4 53 0 100 12 0 0.00 0.00 100.00
... ... ... ... ... ... ... ... ...
292534 11 0 55 2 2 8.35 1.94 46.65
292535 3 3 50 1 1 3.76 0.91 46.24
292536 4 0 50 1 1 3.76 0.91 46.24
292537 39 6 55 1 1 4.13 1.01 50.87
292538 0 0 73 1 1 5.49 1.34 67.51
待还利息 标当前逾期天数 标当前状态 上次还款日期 上次还款本金 上次还款利息 下次计划还款日期 下次计划还款本金 \
0 0.00 0 已还清 2015/7/28 34.20 0.30 NaN NaN
1 0.00 0 已还清 2015/10/19 173.39 1.05 NaN NaN
2 0.00 0 已还清 2016/3/6 44.04 0.38 NaN NaN
3 0.00 0 已还清 2015/5/19 92.34 0.22 NaN NaN
4 9.92 589 逾期中 NaN NaN NaN 2015/5/23 7.66
... ... ... ... ... ... ... ... ...
292534 4.83 0 正常还款中 2017/2/26 4.22 0.93 2017/3/28 4.29
292535 5.24 0 正常还款中 2017/2/9 3.76 0.91 2017/3/5 3.83
292536 5.24 0 正常还款中 2017/2/8 3.76 0.91 2017/3/8 3.83
292537 5.76 0 正常还款中 2017/2/10 4.13 1.01 2017/3/10 4.22
292538 7.64 0 正常还款中 2017/2/20 5.49 1.34 2017/3/20 5.59
下次计划还款利息 recorddate
0 NaN 2016/12/31
1 NaN 2016/12/31
2 NaN 2016/12/31
3 NaN 2016/12/31
4 1.50 2016/12/31
... ... ...
292534 0.86 2017/2/28
292535 0.85 2017/2/28
292536 0.85 2017/2/28
292537 0.93 2017/2/28
292538 1.24 2017/2/28
[292539 rows x 37 columns]
总缺失率 1 2 3 4 5 6 7 rows_with_na = df.isnull().any (axis=1 ).sum () total_missing_rate = round ((rows_with_na / len (df) * 100 ), 2 ) print (f"总缺失率: {total_missing_rate} %" )
总缺失率: 45.15%
手机认证用户借贷笔数 1 2 3 4 loan_phone = df[df['手机认证' ] == '成功认证' ].shape[0 ] print (loan_phone)
153453
户门认证用户借贷情况 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 df_hukou_success = df[df['户口认证' ] == '成功认证' ] avg_loan_amount_hukou_success = df_hukou_success['借款金额' ].mean() avg_loan_duration_hukou_success = df_hukou_success['借款期限' ].mean() avg_interest_rate_hukou_success = df_hukou_success['借款利率' ].mean() avg_age_hukou_success = df_hukou_success['年龄' ].mean() print (f"户口认证成功的用户平均借款金额: {avg_loan_amount_hukou_success:.2 f} " )print (f"户口认证成功的用户平均借款期限: {avg_loan_duration_hukou_success:.2 f} 个月" )print (f"户口认证成功的用户平均借款利率: {avg_interest_rate_hukou_success:.2 f} %" )print (f"户口认证成功的用户平均年龄: {avg_age_hukou_success:.2 f} 岁" )
户口认证成功的用户平均借款金额: 36955.01
户口认证成功的用户平均借款期限: 10.04 个月
户口认证成功的用户平均借款利率: 17.15%
户口认证成功的用户平均年龄: 31.42 岁
征信认证用户借贷情况 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 df_credit_approved = df[df['征信认证' ] == '成功认证' ] avg_loan_amount_credit_approved = df_credit_approved['借款金额' ].mean() avg_loan_duration_credit_approved = df_credit_approved['借款期限' ].mean() avg_interest_rate_credit_approved = df_credit_approved['借款利率' ].mean() avg_age_credit_approved = df_credit_approved['年龄' ].mean() print (f"征信认证成功的用户平均借款金额: {avg_loan_amount_credit_approved:.2 f} " )print (f"征信认证成功的用户平均借款期限: {avg_loan_duration_credit_approved:.2 f} 个月" )print (f"征信认证成功的用户平均借款利率: {avg_interest_rate_credit_approved:.2 f} %" )print (f"征信认证成功的用户平均年龄: {avg_age_credit_approved:.2 f} 岁" )
征信认证成功的用户平均借款金额: 9138.00
征信认证成功的用户平均借款期限: 10.59 个月
征信认证成功的用户平均借款利率: 18.27%
征信认证成功的用户平均年龄: 29.79 岁
性别认证用户还款情况 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 df_with_gender = df[df['性别' ].notna()] repayment_status = df_with_gender.groupby('性别' ).agg({ '借款金额' : 'mean' , '历史成功借款次数' : 'mean' , '历史逾期还款期数' : 'mean' , '总待还本金' : 'mean' }).reset_index() repayment_status.columns = ['性别' , '平均借款金额' , '平均历史成功借款次数' , '平均历史逾期还款期数' , '平均待还本金' ] print (repayment_status)
性别 平均借款金额 平均历史成功借款次数 平均历史逾期还款期数 平均待还本金
0 女 6896.238214 2.651062 17.975806 4706.631430
1 男 9385.546621 2.547655 18.575870 4388.516472
不同性别用户还款占比情况 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 normal_repayment_statuses = ['已还清' , '正常还款中' ] df_per_gender = df df_per_gender['是否正常还款' ] = df_per_gender['标当前状态' ].apply(lambda x: '正常还款' if x in normal_repayment_statuses else '未还清' ) repayment_by_gender = df_per_gender.groupby('性别' )['是否正常还款' ].value_counts(normalize=True ).unstack().fillna(0 ) repayment_by_gender_percentage = repayment_by_gender * 100 print (repayment_by_gender_percentage)
是否正常还款 未还清 正常还款
性别
女 3.216114 96.783886
男 3.948184 96.051816
学历认证用户还款情况 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 df_sty_auth = df[df['学历认证' ] == '成功认证' ] avg_normal_re = df_sty_auth['历史正常还款期数' ].mean() avg_dishor_re = df_sty_auth['历史逾期还款期数' ].mean() org_done_total = df_sty_auth['已还本金' ].sum () fee_done_total = df_sty_auth['已还利息' ].sum () print (f"学历认证用户平均历史正常还款期数: {avg_normal_re} " )print (f"学历认证用户平均历史逾期还款期数: {avg_dishor_re} " )print (f"学历认证用户总已还本金: {org_done_total} " )print (f"学历认证用户总已还利息: {fee_done_total} " )
学历认证用户平均历史正常还款期数: 78.98516016370341
学历认证用户平均历史逾期还款期数: 13.045753352616355
学历认证用户总已还本金: 6445238.179999999
学历认证用户总已还利息: 499930.52000000014
学历认证用户还款占比情况 1 2 3 4 5 6 7 8 9 10 11 12 13 14 df_education_certified = df[df['学历认证' ] == '成功认证' ] status_counts = df_education_certified['标当前状态' ].value_counts() total_certified = df_education_certified.shape[0 ] status_proportions = status_counts / total_certified print (status_proportions)
标当前状态
正常还款中 0.692517
已还清 0.279435
逾期中 0.027097
0 0.000620
0.7 0.000040
2.35 0.000020
0.62 0.000013
5.76 0.000013
1.16 0.000013
1.07 0.000013
4.73 0.000007
1.33 0.000007
0.2 0.000007
2.82 0.000007
0.4 0.000007
0.34 0.000007
2.95 0.000007
3.15 0.000007
2.6 0.000007
2.66 0.000007
5.5 0.000007
2.65 0.000007
0.11 0.000007
5.81 0.000007
1.17 0.000007
1.74 0.000007
0.77 0.000007
4.92 0.000007
2.46 0.000007
0.38 0.000007
6.47 0.000007
1.78 0.000007
0.76 0.000007
3.42 0.000007
0.13 0.000007
1.51 0.000007
0.73 0.000007
0.48 0.000007
3.76 0.000007
4.83 0.000007
0.49 0.000007
3.39 0.000007
Name: count, dtype: float64
不同年龄段用户借款统计 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 bins = [18 , 25 , 35 , 45 , 55 , 65 , 75 ] labels = ['18-24' , '25-34' , '35-44' , '45-54' , '55-64' , '65-74' ] age_df = df age_df['年龄段' ] = pd.cut(age_df['年龄' ], bins=bins, labels=labels, right=False ) age_group_stats = df.groupby('年龄段' ).agg({ '借款金额' : ['sum' , 'mean' , 'count' ] }) age_group_stats.columns = ['借款金额总和' , '平均借款金额' , '借款次数' ] age_group_stats = age_group_stats.reset_index() print (age_group_stats)
年龄段 借款金额总和 平均借款金额 借款次数
0 18-24 296139563 4755.963239 62267
1 25-34 1554537910 8642.275290 179876
2 35-44 527141564 12732.272934 41402
3 45-54 106455104 12088.928458 8806
4 55-64 4524174 24722.262295 183
5 65-74 2500000 500000.000000 5
不同年龄段用户还款占比统计 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 bins = [0 , 24 , 34 , 44 , 54 , 100 ] labels = ['<25' , '25-34' , '35-44' , '45-54' , '55+' ] age_per_df = df age_per_df['年龄段' ] = pd.cut(age_per_df['年龄' ], bins=bins, labels=labels, right=False ) repayment_by_age_group = df.groupby('年龄段' )['已还本金' ].sum () total_repayment = df['已还本金' ].sum () repayment_ratio = (repayment_by_age_group / total_repayment * 100 ).reset_index() repayment_ratio.columns = ['年龄段' , '已还本金占比(%)' ] print (repayment_ratio)
年龄段 已还本金占比(%)
0 <25 14.278337
1 25-34 62.234454
2 35-44 18.792848
3 45-54 4.536181
4 55+ 0.158180
数据分析常用函数 数据筛选 如果是筛选行列的话,通常有以下几种方法: 有时我们需要按条件选择部分列、部分行,一般常用的方法有:
操作
语法
返回结果
选择列
df[col]
Series
按索引选择行
df.loc[label]
Series
按数字索引选择行
df.iloc[loc]
Series
使用切片选择行
df[:5]
DataFrame
用表达式筛选行[3]
df[bool_vec]
DataFrame
除此以外,还有很多方法/函数可以用于“数据筛选”
数据预览 对于探索性数据分析来说,做数据分析前需要先看一下数据的总体概况。
info()
方法用来查看数据集信息
describe()
方法将返回描述性统计信息,这两个函数大家应该都很熟悉了。
describe
方法默认只给出数值型变量的常用统计量,要想对DataFrame中的每个变量进行汇总统计,可以将其中的参数include
设为all
。head()
方法显示数据集的前n行
tail()
方法显示数据集的后n行。
sample()
方法随机看N行的数据。
df.dtypes
检查数据中各列的数据类型。
df.columns
查看所有的列名 。
1 Index(['日期', '销量'], dtype='object')
.dfshape()
获得数据集的大小(长宽)。
len(df)
可以查看总个数
df.count()
则可以查看有效个数,不包含无效值(Nan)
缺失值与重复值 Pandas清洗数据时,判断缺失值一般采用isnull()
方法。isnull().any()
会判断哪些”列”存在缺失值。isnull().sum()
用于将列中为空的个数统计出来。
1 2 3 日期 False 销量 True dtype: bool
发现“销量”这列存在缺失值后,处理办法要么删除dropna()
,要么填充fillna()
。
Pandas清洗数据时,判断重复值一般采用duplicated()
方法。
如果想要直接删除重复值,可以使用drop_duplicates()
方法。
数据值操作 在数值数据操作中,apply()
函数的功能是将一个自定义函数作用于DataFrame的行或者列;applymap()
函数的功能是将自定义函数作用于DataFrame的所有元素。
1 df["数量" ].apply(lambda x: x+1 )
数据批量替换的情况,replace()
是很好的解决方法。它既支持替换全部或者某一行,也支持替换指定的某个或指定的多个数值(用字典的形式)。还可以使用正则表达式替换。
1 df["编号" ].replace(r'BA.$' , value='NEW' , regex=True , inplace = True )
调⽤rank()
⽅法可以实现数据排名。
1 df["排名" ] = df.rank(method="dense" ).astype("int" )
rank()
⽅法中的method
参数,它有5个常⽤选项,可以帮助我们实现不同情况下的排名。
唯一值,unique()
是以数组形式返回列的所有唯一值,而nunique()
返回的是唯一值的个数。
1 2 df["gender" ].unique() df["gender" ].nunique()
clip()
方法,用于对超过或者低于某些数的数值进行截断[1],来保证数值在一定范围。比如每月的迟到天数一定是在0-31天之间。
1 df["迟到天数" ] = df["迟到天数" ].clip(0 ,31 )
行/列操作 rename()
重命名用于更改行列的标签,即行列的索引。可以传入一个字典或者一个函数。在数据预处理中,比较常用。
1 df.rename(columns={'mark' : 'sell' }, inplace=True )
数据清洗时,会将带空值的行删除,此时DataFrame或Series类型的数据不再是连续的索引,可以使用reset_index()
重置索引。
1 df.reset_index(drop=True )
删除行列,可以使用drop()
。
1 df.drop(columns=["mark" ])
行列转置,我们可以使用T
属性获得转置后的DataFrame。
melt()
方法可以将宽表转长表,即表格型数据转为树形数据。
1 df.melt(id_vars="姓名" , var_name="科目" , value_name="成绩" )
pivot()
方法可以将长表转宽表,即树形数据转为表格型数据。
1 df.pivot(index='姓名' , columns='科目' , values='成绩' )
数据分组与数据透视表更是一个常见的需求,groupby()
方法可以用于数据分组。
pivot_table()
数据透视表
数值数据统计运算 在对数值型的数据进行统计运算时,除了有算术运算、比较预算还有各种常见的汇总统计运行函数,具体如下表所示
函数方法
用法释义
count
非NaN数据项计数
sum
求和
mean
平均值
median
中位数
mode
众数
max
最大值
min
最小值
std
标准差
var
方差
quantile
分位数
skew
返回偏态系数
kurt
返回峰态系数
累加cumsum()
。
1 df["累计销量" ] = df["销量" ].cumsum()
文本数据操作 在对文本型的数据进行处理时,我们会大量应用字符串的函数,来实现对一列文本数据进行操作。
函数方法
用法释义
cat
字符串的拼接
contains
判断某个字符串是否包含给定字符
startswith/endswith
判断某个字符串是否以…开头/结尾
get
获取指定位置的字符串
len
计算字符串长度
upper、lower
英文大小写转换
pad/center
在字符串的左边、右边或左右两边添加给定字符
repeat
重复字符串几次
slice_replace
使用给定的字符串,替换指定的位置的字符
split
分割字符串,将一列扩展为多列
strip、rstrip、lstrip
去除空白符、换行符
findall
利用正则表达式,去字符串中匹配,返回查找结果的列表
extract、extractall
接受正则表达式,抽取匹配的字符串(一定要加上括号)