Python快速入门Pandas库

1 数据结构

1.1 Series

创建和初始化

pandas中的Series是一种一维数组的数据结构,可以包含不同数据类型的元素。

以下是Series的创建和初始化的方法:

import pandas as pd

# 通过列表创建Series
data_list = [1, 2, 3, 4]
series_from_list = pd.Series(data_list)
print(series_from_list)
0    1
1    2
2    3
3    4
dtype: int64

上面的例子,在创建Seriespandas自动创建了索引。 我们也可以自己指定标签索引:

# 指定标签索引
data_list = [1, 2, 3, 4]
index_list = ['a', 'b', 'c', 'd'] 

# data表示数据,index表示索引
series_from_list_name = pd.Series(data=data_list, index=index_list)
print(series_from_list)
0    1
1    2
2    3
3    4
dtype: int64
# 通过NumPy数组创建Series
import numpy as np
data_array = np.array([10, 20, 30, 40])
series_from_array = pd.Series(data_array)
print(series_from_array)
0    10
1    20
2    30
3    40
dtype: int32
# 通过字典创建Series
# 该方法字典中的键就是标签索引,值就是数据
data_dict = {'a': 100, 'b': 200, 'c': 300}
series_from_dict = pd.Series(data_dict)
print(series_from_dict)
a    100
b    200
c    300
dtype: int64
索引操作

Series的元素可以通过索引进行访问。索引可以是默认的整数索引,也可以是自定义的标签索引。

# 默认整数索引
print("Element at index 2:", series_from_dict[1]) # Element at index 2: 200

# 自定义标签索引
print("\nElement with label 'b':", series_from_dict['b']) # Element with label 'b': 200
数学运算

Series支持多种数学运算,包括加法、减法、乘法和除法。

# 加法
result_addition = series_from_list + series_from_array
print("Addition result:")
print(result_addition)

# 乘法
result_multiplication = series_from_list * 2
print("\nMultiplication result:")
print(result_multiplication)
Addition result:
0    11
1    22
2    33
3    44
dtype: int64

Multiplication result:
0    2
1    4
2    6
3    8
dtype: int64
对齐操作

在进行数学运算时,Series会自动对齐具有相同标签的元素。

# 对齐操作
data1 = {'a': 10, 'b': 20, 'c': 30}
data2 = {'b': 5, 'c': 15, 'd': 25}
series1 = pd.Series(data1)
series2 = pd.Series(data2)

result_alignment = series1 + series2
print("Result after alignment:")
print(result_alignment)
Result after alignment:
a     NaN
b    25.0
c    45.0
d     NaN
dtype: float64

result_alignment将只包含两个Series中共有的标签,对应位置的元素相加。

1.2 DataFrame

创建和初始化

DataFramepandas中最常用的数据结构之一,它是一个二维标记的数据结构,类似于电子表格或SQL表。下面是一些DataFrame的创建和初始化的方法:

# 通过字典创建DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35],
        'City': ['New York', 'San Francisco', 'Los Angeles']}
df_from_dict = pd.DataFrame(data)
print("DataFrame from dictionary:")
print(df_from_dict)

# 通过列表创建DataFrame
data_list_of_lists = [['Alice', 25, 'New York'],
                      ['Bob', 30, 'San Francisco'],
                      ['Charlie', 35, 'Los Angeles']]
columns = ['Name', 'Age', 'City']
df_from_list = pd.DataFrame(data_list_of_lists, columns=columns)
print("\nDataFrame from list of lists:")
print(df_from_list)
DataFrame from dictionary:
      Name  Age           City
0    Alice   25       New York
1      Bob   30  San Francisco
2  Charlie   35    Los Angeles

DataFrame from list of lists:
      Name  Age           City
0    Alice   25       New York
1      Bob   30  San Francisco
2  Charlie   35    Los Angeles
列操作

DataFrame的列可以通过列名进行访问和操作

# 访问列
names_column = df_from_dict['Name']
print("Names column:")
print(names_column)

# 添加新列
df_from_dict['Country'] = ['USA', 'USA', 'USA']
print("\nDataFrame after adding 'Country' column:")
print(df_from_dict)
Names column:
0      Alice
1        Bob
2    Charlie
Name: Name, dtype: object

DataFrame after adding 'Country' column:
      Name  Age           City Country
0    Alice   25       New York     USA
1      Bob   30  San Francisco     USA
2  Charlie   35    Los Angeles     USA
行操作

DataFrame的行可以通过行索引进行访问和操作

# 通过行索引访问行
row_1 = df_from_dict.loc[0]
print("Row at index 0:")
print(row_1)

# 添加新行
new_row = {'Name': 'David', 'Age': 28, 'City': 'Chicago', 'Country': 'USA'}
df_from_dict = df_from_dict.append(new_row, ignore_index=True) # 新行会被添加到末尾,并使用默认的整数索引进行编号
print("\nDataFrame after adding new row:")
print(df_from_dict)
Row at index 0:
Name          Alice
Age              25
City       New York
Country         USA
Name: 0, dtype: object

DataFrame after adding new row:
      Name  Age           City Country
0    Alice   25       New York     USA
1      Bob   30  San Francisco     USA
2  Charlie   35    Los Angeles     USA
3    David   28        Chicago     USA

在最新的版本中,会提示我们append()函数在未来可能会弃用,我再向大家介绍一下concat()函数。

concat()函数是pandas中用于合并(连接)多个Series或DataFrame的函数。它允许按照指定的轴(默认是行轴)将多个对象进行连接,可以水平连接(按列连接)或垂直连接(按行连接)。下面是concat()abs函数的基本用法和参数说明:

pandas.concat(objs, axis=0, join='outer', ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, sort=False, copy=True)
  • objs: 需要合并的Series或DataFrame对象,可以是一个列表或字典。
  • axis: 指定合并的方向,0表示按行连接(垂直连接),1表示按列连接(水平连接)。默认为0。
  • join: 指定连接方式,'outer’表示并集(对所有索引进行并集),‘inner’表示交集(只对索引的交集进行连接)。默认为’outer’。
  • ignore_index: 是否忽略原始对象的索引,如果为True,则生成新的整数索引。默认为False。
  • keys: 用于创建层次化索引的标签数组或标签列表。如果传递了多个对象(如字典或DataFrame的列表),则需要使用keys参数来创建层次化索引。默认为None。
  • levels: 指定用于层次化索引的唯一值,可以是数组、列表或元组。
  • names: 指定层次化索引的名称。
  • verify_integrity: 检查合并后的对象是否有重复索引。如果设置为True,并且有重复索引,则会引发异常。默认为False。
  • sort: 是否按照字典顺序对结果进行排序。默认为False。
  • copy: 是否对源对象进行复制。默认为True。
import pandas as pd

# 创建两个DataFrame对象
df1 = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
df2 = pd.DataFrame({'A': [7, 8, 9], 'B': [10, 11, 12]})

# 垂直连接(按行连接)
result_vertical = pd.concat([df1, df2])
print("垂直连接:")
print(result_vertical)

# 水平连接(按列连接)
result_horizontal = pd.concat([df1, df2], axis=1)
print("\n水平连接:")
print(result_horizontal)
垂直连接:
   A   B
0  1   4
1  2   5
2  3   6
0  7  10
1  8  11
2  9  12

水平连接:
   A  B  A   B
0  1  4  7  10
1  2  5  8  11
2  3  6  9  12
数据对齐

Series类似,DataFrame在进行操作时会自动对齐具有相同标签的元素。

# 创建两个DataFrame进行对齐操作
data1 = {'Name': ['Alice', 'Bob', 'Charlie'],
         'Age': [25, 30, 35]}
data2 = {'Name': ['David', 'Eve', 'Frank'],
         'Age': [28, 22, 40]}
df1 = pd.DataFrame(data1, index=['a', 'b', 'c'])
df2 = pd.DataFrame(data2, index=['b', 'c', 'd'])

# 对齐操作
result_alignment = df1 + df2
print("\nResult after alignment:")
print(result_alignment)
Result after alignment:
         Name   Age
a         NaN   NaN
b    BobDavid  58.0
c  CharlieEve  57.0
d         NaN   NaN

2 数据操作

2.1 索引和选择

pandas中,对数据进行索引和选择是非常常见的操作。可以通过标签或位置来选择数据。

使用标签

通过标签进行索引和选择是一种常见的方法,可以使用loc[]方法。

# 创建一个示例DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35],
        'City': ['New York', 'San Francisco', 'Los Angeles']}
df = pd.DataFrame(data)

# 使用标签选择行和列
selected_data = df.loc[0, 'Name']
print("Selected data using label:")
print(selected_data)
Selected data using label:
Alice

在上面的示例中,df.loc[0, 'Name']选择了第一行的Name列数据。

使用位置

除了使用标签外,还可以使用位置来进行索引和选择,使用iloc[]方法。

这里要注意的一点是,loc[]中可以混合使用位置索引和标签索引,但是iloc[]中只能使用位置索引。

# 使用位置选择行和列
selected_data = df.iloc[0, 1]
print("\nSelected data using position:")
print(selected_data)
Selected data using position:
25

这里的df.iloc[0, 1]选择了第一行第二列的数据,因为iloc[]使用的是位置而不是标签。

布尔索引

布尔索引是一种非常强大的工具,可以根据条件选择数据。

# 使用布尔索引选择满足条件的行
selected_data = df[df['Age'] > 30]
print("\nSelected data using boolean indexing:")
print(selected_data)
Selected data using boolean indexing:
      Name  Age         City
2  Charlie   35  Los Angeles
重置索引

有时候当我们执行了一些对DataFrame的操作后,DataFrame的索引可能会被打乱,这会影响后面的一些操作,我们通常需要重新设置索引,可以用到reset_index()函数。

df = df.reset_index()

df.reset_index(drop=True, inplace=True)
  • df = df.reset_index():这是最原始的方法,这样操作后会生成一个新的index列存储原有的索引,并且注意一定要重新赋值给df,不然就只是执行了操作,df没有改变。
  • df.reset_index(drop=True, inplace=True):我通常使用这种方法,比较简便
    • drop=True表示不保存原有的索引
    • inplace=True表示在原地执行操作,我们就不需要再次赋值给df

2.2 切片和过滤

切片和过滤是处理数据的常见操作,可以帮助我们根据特定的条件筛选出感兴趣的数据子集。在pandas中,可以使用切片和布尔索引来实现这些操作。

切片也可以使用loc[]方法和iloc[]方法,只需要在切分行和列的时候遵守列表的切片规则就可以了。

行切片

可以使用切片操作选择DataFrame的行。

# 使用行切片选择一定范围的行
sliced_data = df[1:3]
print("Sliced data using row slicing:")
print(sliced_data)
Sliced data using row slicing:
      Name  Age           City
1      Bob   30  San Francisco
2  Charlie   35    Los Angeles

这里的df[1:3]选择了索引为1到2的行(不包括索引为3的行)。

列切片

同样,可以使用切片操作选择DataFrame的列。

# 使用列切片选择一定范围的列
sliced_data = df.loc[:, 'Name':'Age']
print("\nSliced data using column slicing:")
print(sliced_data)
Sliced data using column slicing:
      Name  Age
0    Alice   25
1      Bob   30
2  Charlie   35

这里的df.loc[:, 'Name':'Age']选择了NameAge之间的列。

条件过滤

可以根据特定条件来过滤DataFrame的,该操作其实和布尔索引是同样的原理行。

# 使用条件过滤选择满足条件的行
filtered_data = df[df['Age'] > 30]
print("\nFiltered data using condition:")
print(filtered_data)
Filtered data using condition:
      Name  Age         City
2  Charlie   35  Los Angeles

2.3 赋值和修改

在处理数据时,有时需要对数据进行修改或赋值操作。pandas提供了简单而灵活的方法来实现这些操作。

单值赋值

可以通过索引或切片来对DataFrame中的单个值进行赋值。

# 创建一个示例DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35],
        'City': ['New York', 'San Francisco', 'Los Angeles']}
df = pd.DataFrame(data)

# 单值赋值
df.loc[0, 'Age'] = 26
print("DataFrame after single value assignment:")
print(df)
DataFrame after single value assignment:
      Name  Age           City
0    Alice   26       New York
1      Bob   30  San Francisco
2  Charlie   35    Los Angeles

在上面的示例中,我们将第一行的Age值修改为26。

批量赋值

也可以通过条件或切片来对DataFrame中的多个值进行批量赋值。

# 批量赋值
df.loc[df['Age'] > 30, 'City'] = 'Unknown'
print("\nDataFrame after bulk assignment:")
print(df)
DataFrame after bulk assignment:
      Name  Age           City
0    Alice   26       New York
1      Bob   30  San Francisco
2  Charlie   35        Unknown

这里的df.loc[df['Age'] > 30, 'City'] = 'Unknown'将年龄大于30的行的City列值都修改为Unknown

函数修改

还可以使用函数来修改DataFrame中的现有数据:

# 使用函数修改数据
df['Age'] = df['Age'].apply(lambda x: x + 1)
print("\nDataFrame after applying function:")
print(df)
DataFrame after applying function:
      Name  Age           City
0    Alice   27       New York
1      Bob   31  San Francisco
2  Charlie   36        Unknown
apply()函数

上面提到,我们可以使用函数来修改DataFrame的值,这里我们重点讲解一下apply()函数。

apply()函数是pandas中非常强大和灵活的函数之一,它能够对DataFrame或Series中的每个元素应用自定义函数,从而实现对数据的批量处理。下面详细讲解一下apply()函数的使用。

apply()函数的基本语法:

DataFrame.apply(func, axis=0, raw=False, result_type=None, args=(), **kwds)
  • func: 自定义函数,可以是函数名或lambda函数。
  • axis: 指定对行还是列进行操作,axis=0表示对列操作(默认值),axis=1表示对行操作。
  • raw: 是否直接传递原始数据给函数,默认为False,表示传递的是数据的索引标签。如果为True,则传递的是数据的原始值。
  • result_type: 指定返回结果的数据类型,可选值为None、‘expand’、‘reduce’,默认为None。
  • args: 传递给函数的额外参数,以元组形式传递。

示例:假设我们有一个包含员工工资信息的DataFrame,其中包括员工姓名、工资和工龄。现在我们想要对工资进行调整,比如增加一定的津贴,我们可以使用apply()函数来实现。

import pandas as pd

# 创建示例DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],
        'Salary': [50000, 60000, 70000],
        'Years': [5, 7, 10]}
df = pd.DataFrame(data)

# 定义一个函数,增加津贴
def adjust_salary(salary, allowance):
    return salary + allowance

# 使用apply()函数对Salary列进行操作,增加津贴
allowance = 5000
df['Salary'] = df['Salary'].apply(adjust_salary, args=(allowance,))

print(df)
      Name  Salary  Years
0    Alice   55000      5
1      Bob   65000      7
2  Charlie   75000     10

在这个示例中,我们首先定义了一个adjust_salary()函数,用于将工资和津贴相加。然后,我们使用apply()函数将这个函数应用到Salary列上,实现了对工资的调整。最终输出了调整后的DataFrame。

replace()函数
df['type'] = df['type'].replace({'a': 1, 'b': 2, 'c': 3})

这将把 dftype列中的a 替换为 1,b替换为 2,c 替换为 3。

2.4 排序

排序是数据分析中常用的操作之一,可以帮助我们按照特定的规则重新排列数据。在pandas中,可以使用sort_index()sort_values()函数来实现排序操作。

按索引排序

使用sort_index()函数可以按照索引对DataFrame进行排序,这会将DataFrame按照索引进行升序排序。。

# 按索引排序
df_sorted_index = df.sort_index()
print("DataFrame sorted by index:")
print(df_sorted_index)
DataFrame sorted by index:
      Name  Salary  Years
0    Alice   55000      5
1      Bob   65000      7
2  Charlie   75000     10
按值排序

使用sort_values()函数可以按照列的值对DataFrame进行排序。

# 按值排序
df_sorted_values = df.sort_values(by='Salary', ascending=False)
print("\nDataFrame sorted by values (descending order of Salary):")
print(df_sorted_values)
DataFrame sorted by values (descending order of Salary):
      Name  Salary  Years
2  Charlie   75000     10
1      Bob   65000      7
0    Alice   55000      5

这里的by='Salary'表示按照Salary列的值进行排序,ascending=False表示降序排序,如果为True的话就是升序排列,默认为升序。

多级排序

理解多级排序需要首先理解多级索引。在pandas中,多级索引是指DataFrame中具有多个层级的索引,类似于Excel中的多级行标签。多级索引的情况下,我们可以按照不同的级别进行排序。

让我们以一个简单的示例来说明多级排序的概念和实现:。

import pandas as pd

# 创建一个示例的多级索引Series
index = pd.MultiIndex.from_tuples([('A', 1), ('A', 2), ('B', 1), ('B', 2)])
data = pd.Series([100, 200, 300, 400], index=index)

# 将多级索引Series转换成DataFrame
df_multi_index = data.unstack()
print(df_multi_index)
     1    2
A  100  200
B  300  400
  • pd.MultiIndex.from_tuples(): 这个函数是用来创建多级索引的,它接受一个元组列表作为输入,并返回一个多级索引对象。元组列表中的每个元组代表了一个索引的标签,每个元组的元素对应一个层级的索引标签。例如,[('A', 1), ('A', 2), ('B', 1), ('B', 2)]表示了一个具有两个层级的索引,第一个层级的标签为'A''B',第二个层级的标签为12

  • data.unstack(): 这个方法是将多级索引的Series转换成DataFrame。在我们的示例中,data是一个具有多级索引的Series对象。unstack()方法将多级索引的Series对象转换成DataFrame,其中第一级索引变成了列索引,而第二级索引变成了行索引。换句话说,它将多级索引中的其中一层级(一般是最内层)提取出来作为新的列,形成一个二维的DataFrame。

接下来,让我们对这个多级索引DataFrame进行排序:

# 多级索引排序,第一级升序,第二级降序
df_multi_index_sorted = df_multi_index.sort_index(level=0, ascending=True)
df_multi_index_sorted = df_multi_index.sort_index(level=1, ascending=False)
print(df_multi_index_sorted)
     1    2
B  300  400
A  100  200

在这里,sort_index()函数用于对索引进行排序,level指定了按照第一级和第二级索引进行排序。ascending指定按照升序还是降序排序,True表示升序,False表示降序。

3 数据清洗

数据清洗是数据分析过程中非常重要的一步,它涉及到处理缺失数据、处理重复值以及数据类型转换等操作。在这一部分,我们将详细介绍如何进行数据清洗。

3.1 处理缺失数据

缺失数据在实际数据中经常会出现,可能是由于采集过程中的错误、数据录入问题或者其他原因造成的。在pandas中,我们可以使用一些方法来处理缺失数据:

查找缺失数据

我们可以使用isnull()函数来检查DataFrame中是否存在缺失数据。

import pandas as pd

# 创建示例数据集
data = {'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
        'Age': [20, 25, None, 22, 30],
        'Grade': [85, 90, 75, None, 95],
        'Birthdate': ['1998-05-15', '1996-02-28', '2000-11-10', '1999-08-20', None]}
df = pd.DataFrame(data)

# 查找缺失数据
missing_data = df.isnull()
print("缺失数据情况:")
print(missing_data)
缺失数据情况:
    Name    Age  Grade  Birthdate
0  False  False  False      False
1  False  False  False      False
2  False   True  False      False
3  False  False   True      False
4  False  False  False       True

isnull()函数不接受任何参数,它只是用于查找DataFrame中的缺失数据,并返回一个布尔类型的DataFrame,其中缺失值为True,非缺失值为False

删除缺失数据

使用dropna()函数删除含有缺失数据的行或列

# 删除含有缺失数据的行
df_without_missing = df.dropna(axis=0)

# 删除含有缺失数据的列
df_without_missing_col = df.dropna(axis=1)

除了使用axis指定删除行还是列,我们更常见的是使用subset参数在指定的列范围内搜索缺失值,然后删除有缺失值的行。

# 删除含有缺失数据的行,仅考虑Age列和Grade列
df_without_missing_rows = df.dropna(subset=['Age', 'Grade'])
填充缺失数据

使用fillna()函数用指定的值填充缺失数据,可以使用常数值,也可以使用均值、中位数等统计量。

# 填充缺失数据,用0填充
df_filled = df.fillna(0)

# 填充缺失数据,用均值填充
df_filled_mean = df.fillna(df.mean())

甚至还可以指定某些具体的列使用具体的值

df_filled = df.fillna({'Age': df['Age'].mean(), 'Grade': df['Grade'].median(), 'Birthdate': '1990-01-01'})

3.2 处理重复值

重复值可能会对数据分析产生误导,因此我们需要对其进行处理。

查找重复值

我们可以使用duplicated()函数来检查DataFrame中是否存在重复值。

# 检查重复值
duplicate_rows = df.duplicated()
删除重复值

使用drop_duplicates()函数来删除DataFrame中的重复值。

# 删除重复值
df_unique = df.drop_duplicates()

3.3 数据类型转换

在数据清洗过程中,有时候需要对数据的类型进行转换,例如将字符串类型转换为数字类型,或者处理日期和时间数据类型。

转换整数、浮点数、字符串等
# 将字符串类型转换为整数类型
df['Age'] = df['Age'].astype(int)
处理日期和时间数据类型
# 处理日期和时间数据类型
df['Date'] = pd.to_datetime(df['Date'])

数据清洗综合案例讲解:假设我们有一个包含学生姓名、年龄、成绩和出生日期的数据集。我们将演示如何处理缺失数据、重复值和数据类型转换。

import pandas as pd

# 创建示例数据集
data = {'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Emily'],
        'Age': [20, 25, None, 22, 30],
        'Grade': [85, 90, 75, None, 95],
        'Birthdate': ['1998-05-15', '1996-02-28', '2000-11-10', '1999-08-20', None]}
df = pd.DataFrame(data)

# 显示原始数据集
print("原始数据集:")
print(df)

# 1. 发现缺失数据
missing_data = df.isnull()
print("\n缺失数据情况:")
print(missing_data)

# 2. 删除含有缺失数据的行
df_without_missing = df.dropna()
print("\n删除缺失数据后的数据集:")
print(df_without_missing)

# 3. 填充缺失数据
df_filled = df.fillna({'Age': df['Age'].mean(), 'Grade': df['Grade'].median(), 'Birthdate': '1990-01-01'})
print("\n填充缺失数据后的数据集:")
print(df_filled)

# 4. 发现重复值
duplicate_rows = df.duplicated()
print("\n重复值情况:")
print(duplicate_rows)

# 5. 删除重复值
df_unique = df.drop_duplicates()
print("\n删除重复值后的数据集:")
print(df_unique)

# 6. 数据类型转换
df_filled['Birthdate'] = pd.to_datetime(df_filled['Birthdate'])
print("\n数据类型转换后的数据集:")
print(df_filled)
原始数据集:
      Name   Age  Grade   Birthdate
0    Alice  20.0   85.0  1998-05-15
1      Bob  25.0   90.0  1996-02-28
2  Charlie   NaN   75.0  2000-11-10
3    David  22.0    NaN  1999-08-20
4    Emily  30.0   95.0        None

缺失数据情况:
    Name    Age  Grade  Birthdate
0  False  False  False      False
1  False  False  False      False
2  False   True  False      False
3  False  False   True      False
4  False  False  False       True

删除缺失数据后的数据集:
    Name   Age  Grade   Birthdate
0  Alice  20.0   85.0  1998-05-15
1    Bob  25.0   90.0  1996-02-28

填充缺失数据后的数据集:
      Name    Age  Grade   Birthdate
0    Alice  20.00   85.0  1998-05-15
1      Bob  25.00   90.0  1996-02-28
2  Charlie  24.25   75.0  2000-11-10
3    David  22.00   87.5  1999-08-20
4    Emily  30.00   95.0  1990-01-01

重复值情况:
0    False
1    False
2    False
3    False
4    False
dtype: bool

删除重复值后的数据集:
      Name   Age  Grade   Birthdate
0    Alice  20.0   85.0  1998-05-15
1      Bob  25.0   90.0  1996-02-28
2  Charlie   NaN   75.0  2000-11-10
3    David  22.0    NaN  1999-08-20
4    Emily  30.0   95.0        None

数据类型转换后的数据集:
      Name    Age  Grade  Birthdate
0    Alice  20.00   85.0 1998-05-15
1      Bob  25.00   90.0 1996-02-28
2  Charlie  24.25   75.0 2000-11-10
3    David  22.00   87.5 1999-08-20
4    Emily  30.00   95.0 1990-01-01

4 数据统计和计算

4.1 描述性统计

描述性统计是对数据集的基本统计量进行计算,包括平均值、中位数、标准差、最大值和最小值

# 平均数
mean_grade = df['Grade'].mean()
print("平均成绩:", mean_grade)

# 众数
mode_age = df['Age'].mode()
print("年龄众数:", mode_age)

# 中位数
median_age = df['Age'].median()
print("中位数年龄:", median_age)

# 标准差
std_deviation_grade = df['Grade'].std()
print("成绩标准差:", std_deviation_grade)

# 方差
variance_age = df['Age'].var()
print("年龄方差:", variance_age)

# 最大值
max_grade = df['Grade'].max()
print("最高成绩:", max_grade)

# 最小值
min_grade = df['Grade'].min()
print("最低成绩:", min_grade)

# 四分位数
quartiles_age = df['Age'].quantile([0.25, 0.5, 0.75])
print("年龄四分位数:")
print(quartiles_age)

4.2 聚合和分组

聚合操作是对数据集中的数据进行汇总计算,通常与分组操作一起使用。我们可以使用groupby()函数按照指定的列进行分组,然后对每个组应用.agg()聚合函数。

# 创建示例数据集
data = {'Name': ['Alice', 'Bob', 'Alice', 'Bob', 'Alice'],
        'Age': [20, 25, 22, 22, 30],
        'Grade': [85, 90, 75, 84, 95],
        'Birthdate': ['1998-05-15', '1996-02-28', '2000-11-10', '1999-08-20', '2000-11-10']}
df = pd.DataFrame(data)

# 按照姓名进行分组,并计算每个组的平均年龄和平均成绩
grouped_data = df.groupby('Name').agg({'Age': 'mean', 'Grade': 'median'})
print("按照姓名分组后的聚合结果:")
print(grouped_data)
按照姓名分组后的聚合结果:
        Age  Grade
Name              
Alice  24.0   85.0
Bob    23.5   87.0

4.3 窗口函数

窗口函数是一种在移动窗口上进行计算的方法,例如计算移动平均值、累计和等操作。在pandas中,可以使用rolling()函数来实现窗口函数的计算。

# 使用rolling函数计算移动平均值
rolling_mean = df['Grade'].rolling(window=2).mean()
print("移动平均值:")
print(rolling_mean)
移动平均值:
0     NaN
1    87.5
2    82.5
3    79.5
4    89.5
Name: Grade, dtype: float64

这里的window=2表示窗口大小为2,即每两个数据进行一次计算。

5 数据输入和输出

在实际数据分析过程中,我们通常需要从外部数据源读取数据,或将处理后的数据保存到外部文件中。pandas提供了丰富的功能来实现数据的输入和输出。

5.1 读取数据

pandas支持从多种文件格式中读取数据,包括CSV、Excel、SQL等。

# 从CSV文件读取数据
df_csv = pd.read_csv('data.csv')

# 从Excel文件读取数据
df_excel = pd.read_excel('data.xlsx')

# 从SQL数据库读取数据
import sqlite3
conn = sqlite3.connect('database.db')
query = "SELECT * FROM table_name"
df_sql = pd.read_sql(query, conn)
conn.close()

另外,我们还可以设置参数:

  • header参数用于指定标题行的位置,默认为'infer',表示自动识别。
  • index_col参数用于指定索引列的位置,默认为None,表示不使用任何列作为索引。
# 从CSV文件读取数据,将第一行作为标题行,将第一列作为索引列
df_csv = pd.read_csv('data.csv', header=0, index_col=0)

5.2 写入数据

除了读取数据,pandas也支持将处理后的数据保存到不同格式的文件中。

# 将数据保存到CSV文件
df.to_csv('output.csv', index=False)

# 将数据保存到Excel文件
df.to_excel('output.xlsx', index=False)

# 将数据保存到SQL数据库
conn = sqlite3.connect('new_database.db')
df.to_sql('new_table', conn, index=False, if_exists='replace')
conn.close()
  • header参数用于指定是否将列名写入文件,默认为True
  • index参数用于指定是否将索引列写入文件,默认为True
# 将数据保存到CSV文件,包含标题行和索引列
df.to_csv('output.csv', header=True, index=True)

6 时间序列数据

时间序列数据是一种按照时间顺序排列的数据,通常是固定时间间隔内收集的数据。在pandas中,有许多功能可以处理时间序列数据,包括日期和时间处理、重采样和频率转换以及移动窗口统计等。

6.1 日期和时间处理

pandas提供了强大的日期和时间处理功能,可以解析、操作和格式化日期和时间数据。
pd.date_range()函数参数解释:

  • start: 表示日期范围的起始日期或时间戳。
  • end: 表示日期范围的结束日期或时间戳。
  • periods: 表示要生成的日期数量,这决定了日期范围的长度。
  • freq: 表示日期范围的频率。这可以是一个字符串,也可以是pandas中的DateOffset对象。常用的频率包括:
    • D:天
    • W:周
    • M:月
    • Q:季度
    • A:年
    • 也可以通过+号和数字来表示间隔,例如'5D'表示每隔5天。
# 创建一个日期范围
dates = pd.date_range('2024-01-01', periods=5, freq='D')

# 创建一个包含日期和时间的DataFrame
df_dates = pd.DataFrame({'Date': dates})
print("DataFrame with dates:")
print(df_dates)
DataFrame with dates:
        Date
0 2024-01-01
1 2024-01-02
2 2024-01-03
3 2024-01-04
4 2024-01-05

6.2 重采样和频率转换

重采样是指将时间序列数据从一个频率转换为另一个频率的过程,例如从天到月或从分钟到小时。
resample()函数的常用参数及其含义:

  • rule: 指定重采样的频率,可以是字符串表示的频率别名(如’D’表示天,'M’表示月),也可以是DateOffsetTimedeltaOffset对象。例如,'D’表示每日,'M’表示每月,'W’表示每周。默认为None。

  • on: 指定包含时间序列数据的列名。如果时间序列数据是DataFrame的索引,则不需要使用on参数。但如果时间序列数据是DataFrame的一个普通列,则需要使用on参数来指定这个列的名称。

  • axis: 指定重采样的方向,0表示对行进行重采样,1表示对列进行重采样。默认为0。

  • closed: 指定重采样区间的闭合方式,'right’表示右闭合,'left’表示左闭合,None表示不指定闭合。默认为None。

  • label: 控制聚合后的标签选择方式,'right’表示使用区间的右侧标签作为标签,'left’表示使用区间的左侧标签作为标签,None表示不指定标签。默认为None。

  • convention: 控制聚合时边界的处理方式,'start’表示使用左侧的边界,‘end’表示使用右侧的边界。默认为’start’。

  • kind: 指定聚合时的计算方式,'period’表示以每个区间的开始时间为索引进行聚合,'timestamp’表示以每个区间的中心时间为索引进行聚合。默认为None。

  • loffset: 对于聚合结果的索引偏移量,用于调整聚合结果的索引。默认为None。

  • base: 控制聚合周期相对于时间点的基准,对于周期为N的聚合,'0’表示聚合周期相对于时间点的起始位置,'1’表示相对于时间点的终止位置。默认为0。

# 将时间序列数据从天转换为月
df_monthly = df_dates.resample('M', on='Date').sum()

在上面的例子中,df_dates是一个DataFrame,其中包含一个名为Date的列,该列包含时间序列数据。因此,我们使用了on='Date'参数来指定Date列作为时间序列数据的来源列。

6.3 移动窗口统计

移动窗口统在上面数据统计部分我们已经提到过,但是它也可以用在在时间序列数据上执行滑动窗口计法,例如计算移动平均值或移动总和。

# 计算移动平均值
rolling_mean = df_dates.rolling(window=2).mean()
  • 32
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值