python数据和分析——pandas基础内容

发布时间:2024年01月24日

Pandas 的两个主要的数据结构是 Series 和 DataFrame:

  • Series 是一维标记数组,类似于带有标签的列表。它可以包含不同类型的数据,并且可以通过索引进行访问和操作。
  • DataFrame 是二维表格型数据结构,类似于 SQL 表或 Excel 电子表格。它由多个列组成,每列可以是不同类型的值。

Series

创建一维数组

直接创建

import pandas as pd

data = [1, 2, 3, 4, 5]
series = pd.Series(data)
print(series)
0    1
1    2
2    3
3    4
4    5
dtype: int64

指定索引

import pandas as pd

data = [10,20,30]
index_labels = ['a', 'b', 'c']
series = pd.Series(data, index=index_labels)
print(series)
a  	10  
b  	20  
c  	30  
dtype: int64 

字典创建

import pandas as pd

data_dict = {'a':100,'b':200,'c':300}
series = pd.Series(data_dict)
print(series)
a    100
b    200
c    300
dtype: int64 

修改 Series 对象的数据类型(dtype),可以使用 astype() 方法。astype() 方法允许将 Series 中的数据转换为指定的数据类型

索引和切片

  • 使用整数位置索引
  • 使用标签索引
  • 使用布尔条件进行筛选
  • 隐式整数位置索引: 默认情况下,Series 对象具有隐式的整数位置索引
import pandas as pd

data = [10, 20, 30, 40, 50]
index_labels = ['a', 'b', 'c','d','e']

s=pd.Series(data)[2] # 30

s=pd.Series(data)[2:4]
# 2    30
# 3    40
# dtype: int64

s=pd.Series(data,index=index_labels)['a'] #10

s=pd.Series(data,index=index_labels)['a':'c']
# a    10
# b    20
# c    30
# dtype: int64

x=pd.Series(data)
s=x[x<20]
# 0    10
# dtype: int64

x=pd.Series(data)
s=x.iloc[2] #30
s=x.iloc[2:4]
# 2    30
# 3    40
# dtype: int64

print(s)

查询索引和值:

s = pd.Series(data, index=index_labels)

print(s.index)
# Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
print(s.values)
# [10 20 30 40 50]

读取外部数据

import pandas as pd

# 读取CSV文件
df = pd.read_csv('data.csv')

# 打印数据框内容
print(df)

import pandas as pd

# 读取Excel文件,默认情况下将第一个工作表作为数据框
df = pd.read_excel('data.xlsx')

# 打印数据框内容
print(df)

DataFrame

创建

直接创建

import pandas as pd

df = pd.DataFrame()

索引

data = [['Alice', 25], ['Bob', 30], ['Charlie', 35]]
df = pd.DataFrame(data, columns=['Name', 'Age'])

字典

import pandas as pd

data = {'Name': ['Alice', 'Bob', 'Charlie'], 'Age': [25, 30, 35]}
df = pd.DataFrame(data)

在这里插入图片描述

基本操作

访问列

# 使用列名访问单个列
name_column = df['Name']

# 使用点号访问单个列(仅适用于非保留关键字列名)
name_column = df.Name

# 访问多个列
subset_df = df[['Name', 'Age']]

访问行

# 使用iloc按索引位置访问单个行(基于0索引)
row_0 = df.iloc[0]

# 使用loc按标签名称访问单个行(基于标签索引)
row_alice = df.loc[df['Name'] == 'Alice']

# 根据条件筛选多行
subset_df = df[df['Age'] > 30]

添加新列:

df['City'] = ['New York', 'London', 'Paris']

删除列:

df = df.drop('Age', axis=1)

添加新行:

new_row = pd.Series(['Dave', 40], index=df.columns)
df = df.append(new_row, ignore_index=True)

删除行:

df = df.drop(0)

查询

info(): 提供有关DataFrame的基本信息,包括列名、非空值数量、每列的数据类型等。

import pandas as pd

data = {'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35],
        'City': ['New York', 'London', 'Paris']}
df = pd.DataFrame(data)

df.info()
输出结果:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   Name    3 non-null      object
 1   Age     3 non-null      int64 
 2   City    3 non-null      object
dtypes: int64(1), object(2)
memory usage: ... bytes

在上面的示例中,info()方法提供了有关DataFrame的基本信息。它显示了DataFrame中每个列的名称、非空值数量以及每列数据类型。

describe(): 提供有关数值列(int64或float64)的统计摘要信息,包括计数、均值、标准差、最小值、25%分位数、50%分位数(中位数)、75%分位数和最大值。

import pandas as pd

data = {'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35],
        'City': ['New York', 'London', 'Paris']}
df = pd.DataFrame(data)

df.describe()

输出结果:

             Age
count   3.000000
mean   30.000000
std     5.773503
min    25.000000
25%    27.500000
50%    30.000000
75%    32.500000
max    35.000000

head(): 显示DataFrame的前几行,默认显示前5行。

import pandas as pd

data = {'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eva'],
        'Age': [25, 30, 35, 40, 45],
        'City': ['New York', 'London', 'Paris', 'Tokyo', 'Sydney']}
df = pd.DataFrame(data)

df.head()
输出结果:

      Name  Age      City
0    Alice   25  New York
1      Bob   30    London
2  Charlie   35     Paris
3    David   40     Tokyo
4      Eva   45    Sydney

在上面的示例中,head()方法默认显示DataFrame的前5行。

如果你想要指定显示的行数,可以将所需的行数作为参数传递给head()方法。例如,如果你只想要显示前3行:

df.head(3)
输出结果:

      Name  Age      City
0    Alice   25  New York
1      Bob   30    London
2  Charlie   35     Paris  

tail(): 显示DataFrame的后几行,默认显示最后5行。

import pandas as pd

data = {'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eva'],
        'Age': [25, 30, ,35, ,40, ,45],
        ,'City': ['New York', 'London', 'Paris', 'Tokyo', 'Sydney']}
df = pd.DataFrame(data)

df.tail()
输出结果:

      Name  Age      City
0    Alice   25  New York
1      Bob   30    London
2  Charlie   35     Paris
3    David   40     Tokyo
4      Eva   45    Sydney  

在上面的示例中,tail()方法默认显示DataFrame的最后5行。

同样,你也可以通过传递参数来指定显示的行数。例如,如果你只想要显示最后3行:

df.tail(3)
输出结果:

      Name  Age    City  
2 Charlie   35 Paris    
3   David   40 Tokyo    
4     Eva   45 Sydney   

排序

使用sort_values()方法可以根据指定的列对DataFrame进行升序或降序排序,并且可以同时按照多个列进行排序。这使得你能够对数据进行灵活和定制化的排序操作

import pandas as pd

data = {'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35],
        'City': ['New York', 'London', 'Paris']}
df = pd.DataFrame(data)

# 按照某一列进行升序排序


df_sorted = df.sort_values(by='Age')
print(df_sorted)
输出结果:

      Name  Age      City
0    Alice   25  New York
1      Bob   30    London
2  Charlie   35     Paris

在上面的示例中,我们使用sort_values()方法按照Age列的值对DataFrame进行升序排序。

如果你想要按照多个列进行排序,可以将列名作为一个列表传递给by参数。例如,如果你想要先按照City列进行升序排序,然后再按照Age列进行降序排序:

df_sorted = df.sort_values(by=['City', 'Age'], ascending=[True, False])
print(df_sorted)
输出结果:

      Name  Age      City
1      Bob   30    London
0    Alice   25  New York
2  Charlie   35     Paris  

在上面的示例中,我们通过传递一个包含两个元素的列表给 by 参数来指定多个列,并使用 ascending 参数来指定每个列是否以升序或降序排序。

默认情况下,sort_values()方法会返回一个新的已排序的DataFrame,而不会修改原始的DataFrame。如果你想要在原始DataFrame上进行排序,可以使用inplace=True参数:

df.sort_values(by='Age', inplace=True)
print(df)
输出结果:

      Name  Age      City
0    Alice   25  New York
1      Bob   30    London
2  Charlie   35     Paris  

切片

  • 切片行:

使用位置索引进行切片

import pandas as pd

data = {'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eva'],
        'Age': [25, 30, 35, 40, 45],
        'City': ['New York', 'London', 'Paris', 'Tokyo', 'Sydney']}
df = pd.DataFrame(data)

# 使用位置索引切片
df_slice = df[1:3]
print(df_slice)
输出结果:

      Name  Age    City
1      Bob   30  London
2  Charlie   35   Paris  

使用标签索引切片

df_slice = df.loc[1:3]
print(df_slice)
输出结果:

      Name  Age    City  
1      Bob   30 London  
2 Charlie   35 Paris   
3    David   40 Tokyo   

在上面的示例中,我们使用了不同的方式对DataFrame进行行切片。使用位置索引进行切片时,起始位置是包含在内的,而结束位置是不包含在内的。而使用标签索引进行切片时,起始和结束都是包含在内的。

  • 切片列:

使用列名进行切片:df[‘column_name’],其中 column_name 是要选择的列名。
使用多个列名进行切片:df[[‘column1’, ‘column2’]],其中 ‘column1’ 和 ‘column2’ 是要选择的多个列名。
使用单个列名切片

name_col = df['Name']
print(name_col)
输出结果:

0      Alice
1        Bob
2    Charlie
3      David
4        Eva 
Name: Name, dtype: object  

使用多个列名切片

name_age_cols = df[['Name', 'Age']]
print(name_age_cols)
输出结果:

      Name  Age    
0    Alice   25    
1      Bob   30    
2  Charlie   35    
3    David   40   
4      Eva   45   

在上面的示例中,我们使用了不同的方式对DataFrame进行了列切片。使用单个列名时,返回一个Series对象;使用多个列名时,返回一个新的DataFrame对象。

  • 同时对行和列进行切片操作:
df_slice = df.loc[1:3, ['Name', 'Age']]
print(df_slice)
输出结果:

      Name  Age  
1      Bob   30  
2 Charlie   35  
3    David   40  

布尔索引

布尔索引基于一个条件表达式,返回一个与原始DataFrame形状相同的布尔值Series或DataFrame
在这里插入图片描述

  • 使用比较运算符(如==、>、<、>=、<=等)创建一个布尔表达式,然后将其应用于DataFrame的列
import pandas as pd

data = {'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eva'],
        'Age': [25, 30, 35, 40, 45],
        'City': ['New York', 'London', 'Paris', 'Tokyo' ,'Sydney']}
df = pd.DataFrame(data)

# 使用比较运算符创建布尔表达式
bool_index = df['Age'] > 30
print(bool_index)
输出结果:

0    False
1    False
2     True
3     True
4     True
Name: Age, dtype: bool

将这个布尔表达式应用到DataFrame中以选择满足条件的行

# 使用布尔索引进行数据选择
selected_data = df[bool_index]
print(selected_data)
输出结果:

      Name  Age     City  
2  Charlie   35    Paris  
3    David   40    Tokyo  
4      Eva   45   Sydney  
  • 使用逻辑运算符(如&、|、~等)将多个布尔表达式组合起来
# 使用多个条件进行选择
bool_index = (df['Age'] > 30) & (df['City'] == 'London')
selected_data = df[bool_index]
print(selected_data)
输出结果:

  Name Age    City 
1 Bob   30 London 
  • 使用 .loc[] 进行布尔索引: 可以使用 .loc[] 方法结合布尔索引来同时选择特定行和列
# 使用 .loc[] 进行布尔索引
selected_data = df.loc[df['Age'] > 30, ['Name', 'City']]
print(selected_data)
输出结果:

      Name       City    
2 Charlie       Paris    
3 David         Tokyo    
4 Eva           Sydney   
# 选择 Name 长度大于等于6的行
selected_rows = df.loc[df['Name'].str.len() >= 6]
print(selected_rows)
输出结果:

      Name      City  
0    Alice   New York  
2 Charlie     Paris   

缺失数据的处理

检测缺失数据:
使用 isnull() 方法检测 DataFrame 中的缺失值。该方法返回一个布尔值 DataFrame,其中每个元素表示对应位置是否为缺失值。

import pandas as pd
import numpy as np

data = {'Name': ['Alice', 'Bob', np.nan],
        'Age': [25, np.nan, 35],
        'City': ['New York', 'London', np.nan]}
df = pd.DataFrame(data)

# 检测 DataFrame 中的缺失值
missing_values = df.isnull()
print(missing_values)
输出结果:

    Name    Age   City  
0  False  False  False  
1  False   True  False  
2   True  False   True  

删除包含缺失数据的行或列:
使用 dropna() 方法删除包含任何(默认情况下)或所有(通过设置参数 how='all')缺失值的行。
使用 dropna(axis=1) 方法删除包含任何(默认情况下)或所有(通过设置参数 how='all')缺失值的列。

# 删除包含缺失值的行
df_clean_rows = df.dropna()
print(df_clean_rows)
输出结果:

    Name   Age      City  
0  Alice  25.0 New York   
# 删除包含缺失值的列
df_clean_cols = df.dropna(axis=1)
print(df_clean_cols)
输出结果:

Empty DataFrame
Columns: []
Index: [0, 1, 2]

填充缺失数据:
使用 fillna(value) 方法将 DataFrame 中的缺失值替换为指定的数值或方法。
使用常数填充:fillna(0) 将所有缺失值替换为零。
使用平均数填充:fillna(df.mean()) 将每列中的缺失值替换为该列的平均数。

# 使用常数填充缺失值
df_filled_constant = df.fillna(0)
print(df_filled_constant)
输出结果:

    Name   Age      City  
0  Alice  25.0 New York   
1    Bob   0.0 London     
2      0 35.00         
import pandas as pd

data = {'Name': ['Alice', 'Bob', None],
        'Age': [25, None, 35],
        'City': ['New York', 'London', None]}
df = pd.DataFrame(data)

# 使用前一行数据填充缺失值
df_filled_previous = df.fillna(method='ffill')
print(df_filled_previous)
输出结果:

    Name   Age      City  
0  Alice  25.0 New York   
1    Bob  25.0 London     
2    Bob 35.00 London 

set(df.tolist)

set(df[].tolist()) 是一种将 DataFrame 列中的唯一值提取为集合的方法。它可以用于获取列中的不同值,而不包括重复的值。

import pandas as pd

data = {'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eva'],
        'Age': [25, 30, 35, 40, 45],
        'City': ['New York', 'London', 'Paris', 'Tokyo' ,'Sydney']}
df = pd.DataFrame(data)

# 提取 Name 列中的唯一值
unique_names = set(df['Name'].tolist())
print(unique_names)
输出结果:

{'Charlie', 'David', 'Bob', 'Alice','Eva'}
在上述示例中,我们使用 df['Name'].tolist() 将 DataFrame df 中 Name 列的值转换为列表,并使用 set() 函数将其转换为集合。最后,我们打印了包含唯一名字的集合。

df.join()

import pandas as pd

data1 = {'Name': ['Alice', 'Bob', 'Charlie'],
         'Age': [25, 30, 35]}
df1 = pd.DataFrame(data1)

data2 = {'City': ['New York', 'London', 'Paris'],
         'Salary': [5000, 6000, 7000]}
df2 = pd.DataFrame(data2)

# 使用索引连接两个 DataFrame
joined_df = df1.join(df2)
print(joined_df)
输出结果:

      Name    Age      City Salary  
0    Alice   25.0 New York   5000  
1      Bob   30.0 London     6000  
2 Charlie   35.0 Paris      7000 

分组操作

  • 使用 groupby() 方法根据指定的列或多个列对数据进行分组。这将返回一个 GroupBy 对象,可以在其上应用聚合函数
  • 可以使用单个列名作为参数,也可以使用多个列名的列表作为参数
import pandas as pd

data = {'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eva'],
        'City': ['New York', 'London', 'Paris', 'London' ,'Paris'],
        'Age': [25, 30, 35, 40, 45],
        'Salary': [5000, 6000, 7000, 5500 ,7500]}
df = pd.DataFrame(data)

# 按照 City 列进行分组
grouped_data = df.groupby('City')

print(df)
print('--------------------------------')

# 打印每个分组的内容
for city, group in grouped_data:
    print(f"City: {city}")
    print(group)
    print("\n")

复合索引

单个列索引:
在 Pandas 中,可以使用 set_index() 方法将某一列设置为索引。
这将返回一个新的 DataFrame,并将指定的列作为索引。
索引可以是数值、字符串或其他类型。

import pandas as pd

data = {'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35],
        'City': ['New York', 'London', 'Paris']}
df = pd.DataFrame(data)

# 将 Name 列设置为索引
df_with_index = df.set_index('Name')
print(df_with_index)

输出结果:

         Age      City  
Name                     
Alice    25.0 New York   
Bob      30.0 London     
Charlie 35.0 Paris   

复合索引:
复合索引是由多个列组成的层次化结构。它提供了更灵活和精细的数据访问方式。
可以通过传递多个列名给 set_index() 方法来创建复合索引。

# 将 Name 和 City 列设置为复合索引
df_with_multi_index = df.set_index(['Name', 'City'])
print(df_with_multi_index)
输出结果:

                   Age  
Name    City              
Alice   New York     25.0   
Bob     London       30.0   
Charlie Paris        35.0  

在上述示例中,我们使用 set_index() 方法将 DataFrame df 的 Name 和 City 列设置为复合索引,并打印了带有复合索引的 DataFrame。

可以使用 .loc[] 或 .iloc[] 访问具有复合索引的 DataFrame 中的数据。例如:

# 使用 .loc[] 访问具有复合索引的 DataFrame 中的数据
print(df_with_multi_index.loc[('Alice', 'New York')])
输出结果:

Age      25.0   
Name: (Alice, New York), dtype: float64

.index.unique() 方法来获取索引的唯一值

import pandas as pd

data = {'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35],
        'City': ['New York', 'London', 'Paris']}
df = pd.DataFrame(data)

# 获取索引的唯一值
unique_index_values = df.index.unique()
print(unique_index_values)
输出结果:

Index([0, 1, 2], dtype='object')

.swaplevel()

.swaplevel() 方法用于交换 DataFrame 或 MultiIndex 的层级

  • 交换两个层级的顺序:df.swaplevel(level1, level2, axis)
  • 仅对索引进行操作:index.swaplevel(level1, level2)

时间序列

pd.date_range()

  • start: 范围的起始日期,可以是字符串、datetime对象或Timestamp对象。
  • end: 范围的结束日期,可以是字符串、datetime对象或Timestamp对象。
  • periods: 生成的日期数量,默认为None。如果指定了periods参数,则会根据指定的数量平均间隔生成日期范围。
  • freq:
    日期频率字符串或DateOffset对象,表示每个时间点之间的间隔,默认为’D’(天)。其他常见频率包括’H’(小时)、‘M’(分钟)、‘S’(秒)等。也可以使用自定义频率字符串,如’BQS-JAN’表示每季度开始月份为1月份的工作日频率。
import pandas as pd

df = pd.date_range(start='20220912', end='20230912')

print(df)

DatetimeIndex(['2022-09-12', '2022-09-13', '2022-09-14', '2022-09-15',
               '2022-09-16', '2022-09-17', '2022-09-18', '2022-09-19',
               '2022-09-20', '2022-09-21',
               ...
               '2023-09-03', '2023-09-04', '2023-09-05', '2023-09-06',
               '2023-09-07', '2023-09-08', '2023-09-09', '2023-09-10',
               '2023-09-11', '2023-09-12'],
              dtype='datetime64[ns]', length=366, freq='D')
import pandas as pd

df = pd.date_range(start='20220912', end='20230912',freq='BM')

print(df)

DatetimeIndex(['2022-09-30', '2022-10-31', '2022-11-30', '2022-12-30',
               '2023-01-31', '2023-02-28', '2023-03-31', '2023-04-28',
               '2023-05-31', '2023-06-30', '2023-07-31', '2023-08-31'],
              dtype='datetime64[ns]', freq='BM')
import pandas as pd

df = pd.date_range(start='20220912', periods=10,freq='BM')

print(df)

DatetimeIndex(['2022-09-30', '2022-10-31', '2022-11-30', '2022-12-30',
               '2023-01-31', '2023-02-28', '2023-03-31', '2023-04-28',
               '2023-05-31', '2023-06-30'],
              dtype='datetime64[ns]', freq='BM')

pd.to_datetime

import pandas as pd

# 假设有一个DataFrame df,包含"timeStamp"列
df = pd.DataFrame({'timeStamp': ['2021-01-01', '2021-02-01', '2021-03-01'],
                   'value': [10, 20, 30]})

# 将"timeStamp"列转换为时间戳格式
df['timeStamp'] = pd.to_datetime(df['timeStamp'], format='%Y-%m-%d')

print(df)
输出结果:

   timeStamp  value
0 2021-01-01     10
1 2021-02-01     20
2 2021-03-01     30
通过指定format='%Y-%m-%d'参数来告诉pd.to_datetime()函数输入字符串的日期格式。
这样就可以确保正确地解析日期,并将其转换为pandas中的DateTime对象。

pd.DatetimeIndex
时间索引:可以使用pd.DatetimeIndex对象将日期作为索引来创建Series或DataFram

重采样

重采样是指将时间序列从一个频率转换为另一个频率的过程。重采样可以实现降采样(将高频率数据转换为低频率数据)和升采样(将低频率数据转换为高频率数据)
pandas提供了resample()函数来执行重采样操作。该函数的常用参数包括:

  • rule: 用于指定目标频率的字符串或DateOffset对象。例如,'D’表示每天,'H’表示每小时,'M’表示每月等。
  • how: 用于指定聚合操作的方法。常见的方法包括’mean’(均值)、‘sum’(总和)、‘min’(最小值)、‘max’(最大值)等。
  • closed:
    用于控制区间闭合方式,默认为左闭右闭(‘left’)。还可以选择左开右闭(‘right’)、左闭右开(‘both’)或者左开右开(‘neither’)。
  • label: 用于控制结果索引标签,默认为取区间内第一个时间点作为索引标签。
import pandas as pd

# 创建一个包含10个连续天数的时间序列
dates = pd.date_range(start='2021-01-01', periods=10, freq='D')
data = pd.Series(range(len(dates)), index=dates)

# 将每日数据聚合为每月平均值
monthly_avg = data.resample('M').mean()
print(monthly_avg)
# Output:
# 2021-01-31    15.0
# Freq: M, dtype: float64

# 将每日数据聚合为每周总和
weekly_sum = data.resample('W').sum()
print(weekly_sum)
# Output:
# 2021-01-03     3
# 2021-01-10    28
# Freq: W-SUN, dtype: int64

# 将每月平均值升采样为每天,使用前向填充缺失值
daily_data = monthly_avg.resample('D').ffill()
print(daily_data)

文章来源:https://blog.csdn.net/m0_74033027/article/details/135784752
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。