数据处理与分析:pandas基础+面试习题

1. Pandas 简介

  • Pandas是Python的一个数据分析库,提供高性能、易用的数据结构和数据分析工具

  • 主要用于数据清洗、转换、分析和可视化

  • 核心数据结构:Series(一维)和DataFrame(二维)

  • 支持多种数据格式的读写:CSV、Excel、SQL、JSON等

2. 安装与导入

复制代码
# 安装命令
pip install pandas
pip install pandas numpy matplotlib

# 导入
import pandas as pd
import numpy as np

3. 核心数据结构

3.1 Series (一维标记数组):

代码:

复制代码
# 3.1 Series
print("\n3.1 Series (一维标记数组):")
# 创建Series
print("# 创建Series")
# 从列表创建
ser_list = pd.Series([1, 2, 3, 4, 5])
print(f"从列表创建:\n{ser_list}")

# 从NumPy数组创建
ser_np = pd.Series(np.array([10, 20, 30, 40, 50]))
print(f"\n从NumPy数组创建:\n{ser_np}")

# 自定义索引
ser_index = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
print(f"\n自定义索引:\n{ser_index}")

# 从字典创建
ser_dict = pd.Series({'a': 1, 'b': 2, 'c': 3, 'd': 4})
print(f"\n从字典创建:\n{ser_dict}")

# Series属性
print("\n# Series属性")
print(f"值(values): {ser_index.values}")
print(f"索引(index): {ser_index.index}")
print(f"数据类型(dtype): {ser_index.dtype}")
print(f"形状(shape): {ser_index.shape}")
print(f"大小(size): {ser_index.size}")
print(f"是否为空(isna()): {ser_index.isna().any()}")

结果:

复制代码
3.1 Series (一维标记数组):
# 创建Series
从列表创建:
0    1
1    2
2    3
3    4
4    5
dtype: int64

从NumPy数组创建:
0    10
1    20
2    30
3    40
4    50
dtype: int32

自定义索引:
a    1
b    2
c    3
d    4
e    5
dtype: int64

从字典创建:
a    1
b    2
c    3
d    4
dtype: int64

# Series属性
值(values): [1 2 3 4 5]
索引(index): Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
数据类型(dtype): int64
形状(shape): (5,)
大小(size): 5
是否为空(isna()): False

3.2 DataFrame (二维表格数据结构):

代码:

复制代码
# 3.2 DataFrame
print("\n3.2 DataFrame (二维表格数据结构):")
# 创建DataFrame
print("# 创建DataFrame")

# 从字典创建
data = {
    'Name': ['Alice', 'Bob', 'Charlie', 'David'],
    'Age': [25, 30, 35, 40],
    'City': ['New York', 'London', 'Paris', 'Tokyo'],
    'Salary': [50000, 60000, 70000, 80000]
}

df = pd.DataFrame(data)
print(f"从字典创建:\n{df}")

# 自定义索引
index = ['emp1', 'emp2', 'emp3', 'emp4']
df_index = pd.DataFrame(data, index=index)
print(f"\n自定义索引:\n{df_index}")

# 从NumPy数组创建
df_np = pd.DataFrame(np.random.randn(4, 3), columns=['A', 'B', 'C'], index=index)
print(f"\n从NumPy数组创建:\n{df_np}")

# DataFrame属性
print("\n# DataFrame属性")
print(f"列名(columns): {df.columns}")
print(f"索引(index): {df.index}")
print(f"数据类型(dtypes):\n{df.dtypes}")
print(f"形状(shape): {df.shape}")
print(f"大小(size): {df.size}")
print(f"前5行(head()):\n{df.head()}")
print(f"后5行(tail()):\n{df.tail()}")
print(f"基本信息(info()):")
df.info()
print(f"描述性统计(describe()):\n{df.describe()}")

结果:

复制代码
3.2 DataFrame (二维表格数据结构):
# 创建DataFrame
从字典创建:
      Name  Age      City  Salary
0    Alice   25  New York   50000
1      Bob   30    London   60000
2  Charlie   35     Paris   70000
3    David   40     Tokyo   80000

自定义索引:
         Name  Age      City  Salary
emp1    Alice   25  New York   50000
emp2      Bob   30    London   60000
emp3  Charlie   35     Paris   70000
emp4    David   40     Tokyo   80000

从NumPy数组创建:
             A         B         C
emp1  0.654076  0.894027 -0.638165
emp2 -0.153794  1.286726  1.244924
emp3  0.291976 -0.672659  0.739479
emp4 -0.382255 -0.150715  1.168304

# DataFrame属性
列名(columns): Index(['Name', 'Age', 'City', 'Salary'], dtype='object')
索引(index): RangeIndex(start=0, stop=4, step=1)
数据类型(dtypes):
Name      object
Age        int64
City      object
Salary     int64
dtype: object
形状(shape): (4, 4)
大小(size): 16
前5行(head()):
      Name  Age      City  Salary
0    Alice   25  New York   50000
1      Bob   30    London   60000
2  Charlie   35     Paris   70000
3    David   40     Tokyo   80000
后5行(tail()):
      Name  Age      City  Salary
0    Alice   25  New York   50000
1      Bob   30    London   60000
2  Charlie   35     Paris   70000
3    David   40     Tokyo   80000
基本信息(info()):
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype
---  ------  --------------  -----
 0   Name    4 non-null      object
 1   Age     4 non-null      int64
 2   City    4 non-null      object
 3   Salary  4 non-null      int64
dtypes: int64(2), object(2)
memory usage: 256.0+ bytes
描述性统计(describe()):
             Age        Salary
count   4.000000      4.000000
mean   32.500000  65000.000000
std     6.454972  12909.944487
min    25.000000  50000.000000
25%    28.750000  57500.000000
50%    32.500000  65000.000000
75%    36.250000  72500.000000
max    40.000000  80000.000000

4. 数据选择和索引

4.1 选择列

代码:

复制代码
print("\n4.1 选择列:")
print(f"选择单个列:\n{df['Name']}")
print(f"\n选择多个列:\n{df[['Name', 'Age', 'Salary']]}")

结果:

复制代码
4.1 选择列:
选择单个列:
0      Alice
1        Bob
2    Charlie
3      David
Name: Name, dtype: object

选择多个列:
      Name  Age  Salary
0    Alice   25   50000
1      Bob   30   60000
2  Charlie   35   70000
3    David   40   80000

4.2 选择行

代码:

复制代码
print("\n4.2 选择行:")
# 基于索引标签 (loc)
print(f"基于索引标签(loc):\n{df_index.loc['emp2']}")
print(f"\n基于索引标签选择多行:\n{df_index.loc[['emp1', 'emp3']]}")
print(f"\n基于索引标签选择行和列:\n{df_index.loc[['emp1', 'emp3'], ['Name', 'Salary']]}")

# 基于整数位置 (iloc)
print(f"\n基于整数位置(iloc):\n{df.iloc[1]}")
print(f"\n基于整数位置选择多行:\n{df.iloc[[0, 2]]}")
print(f"\n基于整数位置选择行和列:\n{df.iloc[[0, 2], [0, 3]]}")

结果:

复制代码
4.2 选择行:
基于索引标签(loc):
Name         Bob
Age           30
City      London
Salary     60000
Name: emp2, dtype: object

基于索引标签选择多行:
         Name  Age      City  Salary
emp1    Alice   25  New York   50000
emp3  Charlie   35     Paris   70000

基于索引标签选择行和列:
         Name  Salary
emp1    Alice   50000
emp3  Charlie   70000

基于整数位置(iloc):
Name         Bob
Age           30
City      London
Salary     60000
Name: 1, dtype: object

基于整数位置选择多行:
      Name  Age      City  Salary
0    Alice   25  New York   50000
2  Charlie   35     Paris   70000

基于整数位置选择行和列:
      Name  Salary
0    Alice   50000
2  Charlie   70000

4.3 条件选择

代码:

复制代码
print("\n4.3 条件选择:")
print(f"年龄大于30岁的员工:\n{df[df['Age'] > 30]}")
print(f"\n年龄大于30岁且薪资大于60000的员工:\n{df[(df['Age'] > 30) & (df['Salary'] > 60000)]}")
print(f"\n居住在纽约或东京的员工:\n{df[df['City'].isin(['New York', 'Tokyo'])]}")

结果:

复制代码
4.3 条件选择:
年龄大于30岁的员工:
      Name  Age   City  Salary
2  Charlie   35  Paris   70000
3    David   40  Tokyo   80000

年龄大于30岁且薪资大于60000的员工:
      Name  Age   City  Salary
2  Charlie   35  Paris   70000
3    David   40  Tokyo   80000

居住在纽约或东京的员工:
    Name  Age      City  Salary
0  Alice   25  New York   50000
3  David   40     Tokyo   80000

5. 数据清洗

一般是读取数据文档后进行数据清洗。

5.1 缺失值处理

代码:

复制代码
# 创建包含缺失值的DataFrame
missing_data = {
    'Name': ['Alice', 'Bob', None, 'David'],
    'Age': [25, None, 35, 40],
    'City': ['New York', 'London', 'Paris', None],
    'Salary': [50000, 60000, None, 80000]
}

df_missing = pd.DataFrame(missing_data)
print(f"包含缺失值的DataFrame:\n{df_missing}")

# 5.1 缺失值处理
print("\n5.1 缺失值处理:")
print(f"检测缺失值:\n{df_missing.isna()}")
print(f"\n每列缺失值数量:\n{df_missing.isna().sum()}")

# 删除缺失值
print(f"\n删除包含缺失值的行:\n{df_missing.dropna()}")
print(f"\n删除全部为缺失值的行:\n{df_missing.dropna(how='all')}")
print(f"\n删除缺失值超过1个的行:\n{df_missing.dropna(thresh=3)}")
print(f"\n删除包含缺失值的列:\n{df_missing.dropna(axis=1)}")

# 填充缺失值
print(f"\n用0填充缺失值:\n{df_missing.fillna(0)}")
print(f"\n用平均值填充数值列缺失值:\n{df_missing.fillna(df_missing.mean())}")
print(f"\n用前一个值填充缺失值:\n{df_missing.fillna(method='ffill')}")
print(f"\n用后一个值填充缺失值:\n{df_missing.fillna(method='bfill')}")

结果:

复制代码
5.1 缺失值处理:
检测缺失值:
    Name    Age   City  Salary
0  False  False  False   False
1  False   True  False   False
2   True  False  False    True
3  False  False   True   False

每列缺失值数量:
Name      1
Age       1
City      1
Salary    1
dtype: int64

删除包含缺失值的行:
    Name   Age      City   Salary
0  Alice  25.0  New York  50000.0

删除全部为缺失值的行:
    Name   Age      City   Salary
0  Alice  25.0  New York  50000.0
1    Bob   NaN    London  60000.0
2   None  35.0     Paris      NaN
3  David  40.0      None  80000.0

删除缺失值超过1个的行:
    Name   Age      City   Salary
0  Alice  25.0  New York  50000.0
1    Bob   NaN    London  60000.0
3  David  40.0      None  80000.0

删除包含缺失值的列:
Empty DataFrame
Columns: []
Index: [0, 1, 2, 3]

用0填充缺失值:
    Name   Age      City   Salary
0  Alice  25.0  New York  50000.0
1    Bob   0.0    London  60000.0
2      0  35.0     Paris      0.0
3  David  40.0         0  80000.0
c:/Users/admin/Desktop/Python文件/pandas_basics.py:163: FutureWarning: Dropping of nuisance columns in DataFrame reductions (with 'numeric_only=None') is deprecated; in a future version this will raise TypeError.  Select only valid columns before calling the reduction.
  print(f"\n用平均值填充数值列缺失值:\n{df_missing.fillna(df_missing.mean())}")

用平均值填充数值列缺失值:
    Name        Age      City        Salary
0  Alice  25.000000  New York  50000.000000
1    Bob  33.333333    London  60000.000000
2   None  35.000000     Paris  63333.333333
3  David  40.000000      None  80000.000000

用前一个值填充缺失值:
    Name   Age      City   Salary
0  Alice  25.0  New York  50000.0
1    Bob  25.0    London  60000.0
2    Bob  35.0     Paris  60000.0
3  David  40.0     Paris  80000.0

用后一个值填充缺失值:
    Name   Age      City   Salary
0  Alice  25.0  New York  50000.0
1    Bob  35.0    London  60000.0
2  David  35.0     Paris  80000.0
3  David  40.0      None  80000.0

5.2 重复值处理

代码:

复制代码
# 5.2 重复值处理
print("\n5.2 重复值处理:")
duplicate_data = {
    'Name': ['Alice', 'Bob', 'Alice', 'David'],
    'Age': [25, 30, 25, 40],
    'City': ['New York', 'London', 'New York', 'Tokyo'],
    'Salary': [50000, 60000, 50000, 80000]
}

df_duplicate = pd.DataFrame(duplicate_data)
print(f"包含重复值的DataFrame:\n{df_duplicate}")
print(f"\n检测重复值:\n{df_duplicate.duplicated()}")
print(f"\n删除重复值:\n{df_duplicate.drop_duplicates()}")
print(f"\n基于特定列删除重复值:\n{df_duplicate.drop_duplicates(subset=['Name', 'Age'])}")

结果:

复制代码
5.2 重复值处理:
包含重复值的DataFrame:
    Name  Age      City  Salary
0  Alice   25  New York   50000
1    Bob   30    London   60000
2  Alice   25  New York   50000
3  David   40     Tokyo   80000

检测重复值:
0    False
1    False
2     True
3    False
dtype: bool

删除重复值:
    Name  Age      City  Salary
0  Alice   25  New York   50000
1    Bob   30    London   60000
3  David   40     Tokyo   80000

基于特定列删除重复值:
    Name  Age      City  Salary
0  Alice   25  New York   50000
1    Bob   30    London   60000
3  David   40     Tokyo   80000

5.3 数据类型转换

代码:

复制代码
print("\n5.3 数据类型转换:")
df['Age'] = df['Age'].astype(float)
print(f"将Age列转换为float类型:\n{df.dtypes}")

结果:

复制代码
5.3 数据类型转换:
将Age列转换为float类型:
Name       object
Age       float64
City       object
Salary      int64
dtype: object

6. 数据转换

6.1 添加和删除列

代码:

复制代码
print("\n6.1 添加和删除列:")
# 添加新列
df['Bonus'] = df['Salary'] * 0.1
print(f"添加Bonus列:\n{df}")

# 基于条件创建新列
df['Status'] = np.where(df['Salary'] > 60000, 'Senior', 'Junior')
print(f"\n基于条件创建Status列:\n{df}")

# 删除列
print(f"\n删除Bonus列:\n{df.drop('Bonus', axis=1)}")

结果:

复制代码
6.1 添加和删除列:
添加Bonus列:
      Name   Age      City  Salary   Bonus
0    Alice  25.0  New York   50000  5000.0
1      Bob  30.0    London   60000  6000.0
2  Charlie  35.0     Paris   70000  7000.0
3    David  40.0     Tokyo   80000  8000.0

基于条件创建Status列:
      Name   Age      City  Salary   Bonus  Status
0    Alice  25.0  New York   50000  5000.0  Junior
1      Bob  30.0    London   60000  6000.0  Junior
2  Charlie  35.0     Paris   70000  7000.0  Senior
3    David  40.0     Tokyo   80000  8000.0  Senior

删除Bonus列:
      Name   Age      City  Salary  Status
0    Alice  25.0  New York   50000  Junior
1      Bob  30.0    London   60000  Junior
2  Charlie  35.0     Paris   70000  Senior
3    David  40.0     Tokyo   80000  Senior

6.2 修改列名

代码:

复制代码
# 6.2 修改列名
print("\n6.2 修改列名:")
df_renamed = df.rename(columns={'Name': 'EmployeeName', 'Salary': 'AnnualSalary'})
print(f"修改列名:\n{df_renamed}")

结果:

复制代码
6.2 修改列名:
修改列名:
  EmployeeName   Age      City  AnnualSalary   Bonus  Status
0        Alice  25.0  New York         50000  5000.0  Junior
1          Bob  30.0    London         60000  6000.0  Junior
2      Charlie  35.0     Paris         70000  7000.0  Senior
3        David  40.0     Tokyo         80000  8000.0  Senior

6.3 排序数据

代码:

复制代码
print("\n6.3 排序数据:")
# 按列值排序
print(f"按Age列升序排序:\n{df.sort_values('Age')}")
print(f"\n按Salary列降序排序:\n{df.sort_values('Salary', ascending=False)}")

# 按索引排序
print(f"\n按索引排序:\n{df.sort_index()}")

结果:

复制代码
6.3 排序数据:
按Age列升序排序:
      Name   Age      City  Salary   Bonus  Status
0    Alice  25.0  New York   50000  5000.0  Junior
1      Bob  30.0    London   60000  6000.0  Junior
2  Charlie  35.0     Paris   70000  7000.0  Senior
3    David  40.0     Tokyo   80000  8000.0  Senior

按Salary列降序排序:
      Name   Age      City  Salary   Bonus  Status
3    David  40.0     Tokyo   80000  8000.0  Senior
2  Charlie  35.0     Paris   70000  7000.0  Senior
1      Bob  30.0    London   60000  6000.0  Junior
0    Alice  25.0  New York   50000  5000.0  Junior

按索引排序:
      Name   Age      City  Salary   Bonus  Status
0    Alice  25.0  New York   50000  5000.0  Junior
1      Bob  30.0    London   60000  6000.0  Junior
2  Charlie  35.0     Paris   70000  7000.0  Senior
3    David  40.0     Tokyo   80000  8000.0  Senior

6.4 应用函数

代码:

复制代码
# 6.4 应用函数
print("\n6.4 应用函数:")
# 对单列应用函数
df['Salary'] = df['Salary'].apply(lambda x: x * 1.05)  # 涨薪5%
print(f"对Salary列应用涨薪函数:\n{df}")

# 对多列应用函数
df[['Age', 'Salary']] = df[['Age', 'Salary']].apply(np.round)
print(f"\n对多列应用四舍五入函数:\n{df}")

# 对整个DataFrame应用函数
df_np_rounded = df_np.applymap(lambda x: round(x, 2))
print(f"\n对整个DataFrame应用四舍五入函数:\n{df_np_rounded}")

结果:

复制代码
6.4 应用函数:
对Salary列应用涨薪函数:
      Name   Age      City   Salary   Bonus  Status
0    Alice  25.0  New York  52500.0  5000.0  Junior
1      Bob  30.0    London  63000.0  6000.0  Junior
2  Charlie  35.0     Paris  73500.0  7000.0  Senior
3    David  40.0     Tokyo  84000.0  8000.0  Senior

对多列应用四舍五入函数:
      Name   Age      City   Salary   Bonus  Status
0    Alice  25.0  New York  52500.0  5000.0  Junior
1      Bob  30.0    London  63000.0  6000.0  Junior
2  Charlie  35.0     Paris  73500.0  7000.0  Senior
3    David  40.0     Tokyo  84000.0  8000.0  Senior

对整个DataFrame应用四舍五入函数:
         A     B     C
emp1  0.65  0.89 -0.64
emp2 -0.15  1.29  1.24
emp3  0.29 -0.67  0.74
emp4 -0.38 -0.15  1.17

7. 数据分组和聚合

7.1 分组

代码:

复制代码
print("\n7. 数据分组和聚合:")

# 创建示例数据
sales_data = {
    'Date': pd.date_range('2023-01-01', periods=12),
    'Product': ['A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B'],
    'Region': ['North', 'North', 'South', 'South', 'East', 'East', 'West', 'West', 'North', 'North', 'South', 'South'],
    'Sales': [100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650]
}

df_sales = pd.DataFrame(sales_data)
print(f"销售数据:\n{df_sales}")

# 7.1 分组
print("\n7.1 分组:")
grouped = df_sales.groupby('Product')
print(f"按产品分组:")
for name, group in grouped:
    print(f"\n产品 {name}:\n{group}")

# 多列分组
grouped_multi = df_sales.groupby(['Product', 'Region'])
print(f"\n按产品和地区分组:")
for name, group in grouped_multi:
    print(f"\n{name}:\n{group}")

结果:

复制代码
7. 数据分组和聚合:
销售数据:
         Date Product Region  Sales
0  2023-01-01       A  North    100
1  2023-01-02       B  North    150
2  2023-01-03       A  South    200
3  2023-01-04       B  South    250
4  2023-01-05       A   East    300
5  2023-01-06       B   East    350
6  2023-01-07       A   West    400
7  2023-01-08       B   West    450
8  2023-01-09       A  North    500
9  2023-01-10       B  North    550
10 2023-01-11       A  South    600
11 2023-01-12       B  South    650

7.1 分组:
按产品分组:

产品 A:
         Date Product Region  Sales
0  2023-01-01       A  North    100
2  2023-01-03       A  South    200
4  2023-01-05       A   East    300
6  2023-01-07       A   West    400
8  2023-01-09       A  North    500
10 2023-01-11       A  South    600

产品 B:
         Date Product Region  Sales
1  2023-01-02       B  North    150
3  2023-01-04       B  South    250
5  2023-01-06       B   East    350
7  2023-01-08       B   West    450
9  2023-01-10       B  North    550
11 2023-01-12       B  South    650

按产品和地区分组:

('A', 'East'):
        Date Product Region  Sales
4 2023-01-05       A   East    300

('A', 'North'):
        Date Product Region  Sales
0 2023-01-01       A  North    100
8 2023-01-09       A  North    500

('A', 'South'):
         Date Product Region  Sales
2  2023-01-03       A  South    200
10 2023-01-11       A  South    600

('A', 'West'):
        Date Product Region  Sales
6 2023-01-07       A   West    400

('B', 'East'):
        Date Product Region  Sales
5 2023-01-06       B   East    350

('B', 'North'):
        Date Product Region  Sales
1 2023-01-02       B  North    150
9 2023-01-10       B  North    550

('B', 'South'):
         Date Product Region  Sales
3  2023-01-04       B  South    250
11 2023-01-12       B  South    650

('B', 'West'):
        Date Product Region  Sales
7 2023-01-08       B   West    450

7.2 聚合函数

代码:

复制代码
print("\n7.2 聚合函数:")
print(f"按产品分组的销售额总和:\n{grouped['Sales'].sum()}")
print(f"\n按产品分组的销售额平均值:\n{grouped['Sales'].mean()}")
print(f"\n按产品分组的销售额统计信息:\n{grouped['Sales'].describe()}")

# 多个聚合函数
print(f"\n按产品分组的多个聚合函数:\n{grouped['Sales'].agg(['sum', 'mean', 'max', 'min', 'count'])}")

# 为不同列应用不同的聚合函数
print(f"\n为不同列应用不同的聚合函数:\n{grouped.agg({'Sales': ['sum', 'mean'], 'Date': 'count'})}")

结果:

复制代码
7.2 聚合函数:
按产品分组的销售额总和:
Product
A    2100
B    2400
Name: Sales, dtype: int64

按产品分组的销售额平均值:
Product
A    350.0
B    400.0
Name: Sales, dtype: float64

按产品分组的销售额统计信息:
         count   mean         std    min    25%    50%    75%    max
Product
A          6.0  350.0  187.082869  100.0  225.0  350.0  475.0  600.0
B          6.0  400.0  187.082869  150.0  275.0  400.0  525.0  650.0

按产品分组的多个聚合函数:
          sum   mean  max  min  count
Product
A        2100  350.0  600  100      6
B        2400  400.0  650  150      6

为不同列应用不同的聚合函数:
        Sales         Date
          sum   mean count
Product
A        2100  350.0     6
B        2400  400.0     6

7.3 转换

代码:

复制代码
print("\n7.3 转换:")
# 计算每个产品的销售额占比
df_sales['Sales_Percentage'] = grouped['Sales'].transform(lambda x: x / x.sum())
print(f"计算每个产品的销售额占比:\n{df_sales}")

结果:

复制代码
7.3 转换:
计算每个产品的销售额占比:
         Date Product Region  Sales  Sales_Percentage
0  2023-01-01       A  North    100          0.047619
1  2023-01-02       B  North    150          0.062500
2  2023-01-03       A  South    200          0.095238
3  2023-01-04       B  South    250          0.104167
4  2023-01-05       A   East    300          0.142857
5  2023-01-06       B   East    350          0.145833
6  2023-01-07       A   West    400          0.190476
7  2023-01-08       B   West    450          0.187500
8  2023-01-09       A  North    500          0.238095
9  2023-01-10       B  North    550          0.229167
10 2023-01-11       A  South    600          0.285714
11 2023-01-12       B  South    650          0.270833

8. 数据合并和连接

8.1 合并 (Merge)

代码:

复制代码
# 创建示例数据
left_data = {
    'ID': [1, 2, 3, 4, 5],
    'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'Department': ['HR', 'IT', 'Sales', 'IT', 'Finance']
}

right_data = {
    'ID': [3, 4, 5, 6, 7],
    'Salary': [50000, 60000, 70000, 80000, 90000],
    'Bonus': [5000, 6000, 7000, 8000, 9000]
}

df_left = pd.DataFrame(left_data)
df_right = pd.DataFrame(right_data)

print(f"左表:\n{df_left}")
print(f"\n右表:\n{df_right}")

# 8.1 合并 (Merge)
print("\n8.1 合并 (Merge):")
# 内连接
print(f"内连接:\n{pd.merge(df_left, df_right, on='ID')}")

# 左连接
print(f"\n左连接:\n{pd.merge(df_left, df_right, on='ID', how='left')}")

# 右连接
print(f"\n右连接:\n{pd.merge(df_left, df_right, on='ID', how='right')}")

# 外连接
print(f"\n外连接:\n{pd.merge(df_left, df_right, on='ID', how='outer')}")

结果:

复制代码
8. 数据合并和连接:
左表:
   ID     Name Department
0   1    Alice         HR
1   2      Bob         IT
2   3  Charlie      Sales
3   4    David         IT
4   5      Eve    Finance

右表:
   ID  Salary  Bonus
0   3   50000   5000
1   4   60000   6000
2   5   70000   7000
3   6   80000   8000
4   7   90000   9000

8.1 合并 (Merge):
内连接:
   ID     Name Department  Salary  Bonus
0   3  Charlie      Sales   50000   5000
1   4    David         IT   60000   6000
2   5      Eve    Finance   70000   7000

左连接:
   ID     Name Department   Salary   Bonus
0   1    Alice         HR      NaN     NaN
1   2      Bob         IT      NaN     NaN
2   3  Charlie      Sales  50000.0  5000.0
3   4    David         IT  60000.0  6000.0
4   5      Eve    Finance  70000.0  7000.0

右连接:
   ID     Name Department  Salary  Bonus
0   3  Charlie      Sales   50000   5000
1   4    David         IT   60000   6000
2   5      Eve    Finance   70000   7000
3   6      NaN        NaN   80000   8000
4   7      NaN        NaN   90000   9000

外连接:
   ID     Name Department   Salary   Bonus
0   1    Alice         HR      NaN     NaN
1   2      Bob         IT      NaN     NaN
2   3  Charlie      Sales  50000.0  5000.0
3   4    David         IT  60000.0  6000.0
4   5      Eve    Finance  70000.0  7000.0
5   6      NaN        NaN  80000.0  8000.0
6   7      NaN        NaN  90000.0  9000.0

8.2 连接 (Concat)

代码:

复制代码
# 8.2 连接 (Concat)
print("\n8.2 连接 (Concat):")
# 垂直连接
print(f"垂直连接:\n{pd.concat([df_left, df_right])}")
print(f"\n垂直连接(忽略索引):\n{pd.concat([df_left, df_right], ignore_index=True)}")

# 水平连接
print(f"\n水平连接:\n{pd.concat([df_left, df_right], axis=1)}")

结果:

复制代码
8.2 连接 (Concat):
垂直连接:
   ID     Name Department   Salary   Bonus
0   1    Alice         HR      NaN     NaN
1   2      Bob         IT      NaN     NaN
2   3  Charlie      Sales      NaN     NaN
3   4    David         IT      NaN     NaN
4   5      Eve    Finance      NaN     NaN
0   3      NaN        NaN  50000.0  5000.0
1   4      NaN        NaN  60000.0  6000.0
2   5      NaN        NaN  70000.0  7000.0
3   6      NaN        NaN  80000.0  8000.0
4   7      NaN        NaN  90000.0  9000.0

垂直连接(忽略索引):
   ID     Name Department   Salary   Bonus
0   1    Alice         HR      NaN     NaN
1   2      Bob         IT      NaN     NaN
2   3  Charlie      Sales      NaN     NaN
3   4    David         IT      NaN     NaN
4   5      Eve    Finance      NaN     NaN
5   3      NaN        NaN  50000.0  5000.0
6   4      NaN        NaN  60000.0  6000.0
7   5      NaN        NaN  70000.0  7000.0
8   6      NaN        NaN  80000.0  8000.0
9   7      NaN        NaN  90000.0  9000.0

水平连接:
   ID     Name Department  ID  Salary  Bonus
0   1    Alice         HR   3   50000   5000
1   2      Bob         IT   4   60000   6000
2   3  Charlie      Sales   5   70000   7000
3   4    David         IT   6   80000   8000
4   5      Eve    Finance   7   90000   9000

9. 数据可视化

9.1 基本图表(注意这里的文件路径要改成自己想要储存的地方)

代码:

复制代码
print("\n9.1 基本图表:")

# 创建示例数据
chart_data = {
    'Month': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
    'Sales': [100, 150, 200, 250, 300, 350],
    'Expenses': [80, 120, 150, 180, 200, 220]
}

df_chart = pd.DataFrame(chart_data)

# 折线图
print("创建折线图...")
df_chart.plot(x='Month', y=['Sales', 'Expenses'], kind='line', title='月度销售与支出', figsize=(10, 6))
plt.savefig('c:\\Users\\admin\\Desktop\\Python文件\\line_chart.png')
plt.close()

# 柱状图
print("创建柱状图...")
df_chart.plot(x='Month', y=['Sales', 'Expenses'], kind='bar', title='月度销售与支出', figsize=(10, 6))
plt.savefig('c:\\Users\\admin\\Desktop\\Python文件\\bar_chart.png')
plt.close()

# 饼图
print("创建饼图...")
df_chart['Sales'].plot(kind='pie', labels=df_chart['Month'], title='月度销售分布', autopct='%1.1f%%', figsize=(8, 8))
plt.axis('equal')
plt.savefig('c:\\Users\\admin\\Desktop\\Python文件\\pie_chart.png')
plt.close()

# 散点图
print("创建散点图...")
df_chart.plot(x='Month', y='Sales', kind='scatter', title='月度销售散点图', s=100, figsize=(10, 6))
plt.savefig('c:\\Users\\admin\\Desktop\\Python文件\\scatter_chart.png')
plt.close()

print("所有图表已保存到桌面Python文件目录")

结果:

复制代码
9.1 基本图表:
创建折线图...
创建柱状图...
创建饼图...
创建散点图...
所有图表已保存到桌面Python文件目录

图表还是比较清晰的。

折线统计图

柱状图

饼图

散点图

10. 时间序列处理

10.1 创建时间序列

代码:

复制代码
# 10.1 创建时间序列
print("\n10.1 创建时间序列:")
# 创建日期范围
dates = pd.date_range('2023-01-01', periods=100, freq='D')
print(f"创建日期范围:\n{dates[:10]}")

# 创建时间序列数据
ts = pd.Series(np.random.randn(100), index=dates)
print(f"\n创建时间序列数据:\n{ts[:10]}")

结果:

复制代码
10.1 创建时间序列:
创建日期范围:
DatetimeIndex(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04',
               '2023-01-05', '2023-01-06', '2023-01-07', '2023-01-08',
               '2023-01-09', '2023-01-10'],
              dtype='datetime64[ns]', freq='D')

创建时间序列数据:
2023-01-01   -0.000344
2023-01-02   -0.127895
2023-01-03   -0.875382
2023-01-04   -0.509991
2023-01-05   -0.103893
2023-01-06    0.220112
2023-01-07    0.984742
2023-01-08    0.041398
2023-01-09   -0.113806
2023-01-10    0.186574
Freq: D, dtype: float64

10.2 时间序列索引

代码:

复制代码
# 10.2 时间序列索引
print("\n10.2 时间序列索引:")
print(f"选择特定日期:\n{ts['2023-01-15']}")
print(f"\n选择特定月份:\n{ts['2023-02'].head()}")
print(f"\n选择日期范围:\n{ts['2023-01-15':'2023-01-20']}")

结果:

复制代码
10.2 时间序列索引:
选择特定日期:
1.1273307155980765

选择特定月份:
2023-02-01   -0.181408
2023-02-02   -0.530643
2023-02-03    0.430166
2023-02-04   -0.535271
2023-02-05   -0.148329
Freq: D, dtype: float64

选择日期范围:
2023-01-15    1.127331
2023-01-16   -0.675183
2023-01-17    0.537903
2023-01-18    0.571938
2023-01-19    2.215875
2023-01-20    1.313192
Freq: D, dtype: float64

10.3 时间序列重采样

代码:

复制代码
# 10.3 时间序列重采样
print("\n10.3 时间序列重采样:")
print(f"按周重采样(平均值):\n{ts.resample('W').mean().head()}")
print(f"\n按月重采样(总和):\n{ts.resample('M').sum().head()}")

结果:

复制代码
10.3 时间序列重采样:
按周重采样(平均值):
2023-01-01   -0.000344
2023-01-08   -0.052987
2023-01-15    0.720680
2023-01-22    0.242080
2023-01-29    0.360371
Freq: W-SUN, dtype: float64

按月重采样(总和):
2023-01-31    7.920179
2023-02-28    0.066653
2023-03-31    1.702473
2023-04-30    0.428954
Freq: M, dtype: float64

10.4 移动窗口

代码:

复制代码
# 10.4 移动窗口
print("\n10.4 移动窗口:")
print(f"7天移动平均:\n{ts.rolling(window=7).mean().head(10)}")
print(f"\n30天移动总和:\n{ts.rolling(window=30).sum().head(35)}")

结果:

复制代码
10.4 移动窗口:
7天移动平均:
2023-01-01         NaN
2023-01-02         NaN
2023-01-03         NaN
2023-01-04         NaN
2023-01-05         NaN
2023-01-06         NaN
2023-01-07   -0.058950
2023-01-08   -0.052987
2023-01-09   -0.050974
2023-01-10    0.100734
Freq: D, dtype: float64

30天移动总和:
2023-01-01         NaN
2023-01-02         NaN
2023-01-03         NaN
2023-01-04         NaN
2023-01-05         NaN
2023-01-06         NaN
2023-01-07         NaN
2023-01-08         NaN
2023-01-09         NaN
2023-01-10         NaN
2023-01-11         NaN
2023-01-12         NaN
2023-01-13         NaN
2023-01-14         NaN
2023-01-15         NaN
2023-01-16         NaN
2023-01-17         NaN
2023-01-18         NaN
2023-01-19         NaN
2023-01-20         NaN
2023-01-21         NaN
2023-01-22         NaN
2023-01-23         NaN
2023-01-24         NaN
2023-01-25         NaN
2023-01-26         NaN
2023-01-27         NaN
2023-01-28         NaN
2023-01-29         NaN
2023-01-30    9.008928
2023-01-31    7.920523
2023-02-01    7.867010
2023-02-02    8.211748
2023-02-03    9.151906
2023-02-04    8.720528
Freq: D, dtype: float64

11. 高级功能

11.1 透视表

代码:

复制代码
# 11.1 透视表
print("\n11.1 透视表:")
pivot = pd.pivot_table(df_sales, values='Sales', index=['Product'], columns=['Region'], aggfunc=np.sum)
print(f"产品和地区的销售透视表:\n{pivot}")

结果:

复制代码
11.1 透视表:
产品和地区的销售透视表:
Region   East  North  South  West
Product
A         300    600    800   400
B         350    700    900   450

11.2 交叉表

代码:

复制代码
# 11.2 交叉表
print("\n11.2 交叉表:")
cross = pd.crosstab(df_sales['Product'], df_sales['Region'])
print(f"产品和地区的交叉表:\n{cross}")

结果:

复制代码
11.2 交叉表:
产品和地区的交叉表:
Region   East  North  South  West
Product
A           1      2      2     1
B           1      2      2     1

11.3 数据透视和堆叠

代码:

复制代码
# 11.3 数据透视和堆叠
print("\n11.3 数据透视和堆叠:")
# 堆叠
stacked = pivot.stack()
print(f"堆叠后:\n{stacked}")

# 取消堆叠
unstacked = stacked.unstack()
print(f"\n取消堆叠后:\n{unstacked}")

结果:

复制代码
11.3 数据透视和堆叠:
堆叠后:
Product  Region
A        East      300
         North     600
         South     800
         West      400
B        East      350
         North     700
         South     900
         West      450
dtype: int64

取消堆叠后:
Region   East  North  South  West
Product
A         300    600    800   400
B         350    700    900   450

12. 数据输入/输出(注意文件保存路径的替换)

12.1 CSV文件

代码:

复制代码
# 12.1 CSV文件
print("\n12.1 CSV文件:")
# 保存为CSV文件
df.to_csv('c:\\Users\\admin\\Desktop\\Python文件\\employee_data.csv', index=False)
print("DataFrame已保存为employee_data.csv")

# 读取CSV文件
df_csv = pd.read_csv('c:\\Users\\admin\\Desktop\\Python文件\\employee_data.csv')
print(f"\n读取CSV文件:\n{df_csv}")

结果:

复制代码
12.1 CSV文件:
DataFrame已保存为employee_data.csv

读取CSV文件:
      Name   Age      City   Salary   Bonus  Status
0    Alice  25.0  New York  52500.0  5000.0  Junior
1      Bob  30.0    London  63000.0  6000.0  Junior
2  Charlie  35.0     Paris  73500.0  7000.0  Senior
3    David  40.0     Tokyo  84000.0  8000.0  Senior

12.2 Excel文件

代码:

复制代码
# 12.2 Excel文件
print("\n12.2 Excel文件:")
# 保存为Excel文件
df.to_excel('c:\\Users\\admin\\Desktop\\Python文件\\employee_data.xlsx', index=False, sheet_name='Employees')
print("DataFrame已保存为employee_data.xlsx")

# 读取Excel文件
df_excel = pd.read_excel('c:\\Users\\admin\\Desktop\\Python文件\\employee_data.xlsx', sheet_name='Employees')
print(f"\n读取Excel文件:\n{df_excel}")

结果:

复制代码
12.3 JSON文件:
DataFrame已保存为employee_data.json

读取JSON文件:
      Name  Age      City  Salary  Bonus  Status
0    Alice   25  New York   52500   5000  Junior
1      Bob   30    London   63000   6000  Junior
2  Charlie   35     Paris   73500   7000  Senior
3    David   40     Tokyo   84000   8000  Senior

12.3 JSON文件

代码:

复制代码
# 12.3 JSON文件
print("\n12.3 JSON文件:")
# 保存为JSON文件
df.to_json('c:\\Users\\admin\\Desktop\\Python文件\\employee_data.json', orient='records')
print("DataFrame已保存为employee_data.json")

# 读取JSON文件
df_json = pd.read_json('c:\\Users\\admin\\Desktop\\Python文件\\employee_data.json')
print(f"\n读取JSON文件:\n{df_json}")

结果:

复制代码
12.3 JSON文件:
DataFrame已保存为employee_data.json

读取JSON文件:
      Name  Age      City  Salary  Bonus  Status
0    Alice   25  New York   52500   5000  Junior
1      Bob   30    London   63000   6000  Junior
2  Charlie   35     Paris   73500   7000  Senior
3    David   40     Tokyo   84000   8000  Senior

13.面试习题

题目 1:选择题

在Pandas中,Series是:

A. 一维标签化数组

B. 二维标签化数组

C. 数据库表格

D. 时间序列数据结构
-**A. 一维标签化数组**

题目 2:

以下哪个方法用于读取CSV文件到DataFrame?

A. pd.read_csv()

B. pd.to_csv()

C. pd.DataFrame()

D. pd.read_excel()
**A. pd.read_csv()**

题目 3:判断题

Pandas的DataFrame可以包含不同类型的数据。(对/错)

在Pandas中,NaN表示缺失值。(对/错)

错、对

题目 4:编程题

请使用Pandas读取一个CSV文件,并显示前5行数据。

复制代码
import pandas as pd

# 假设CSV文件名为"data.csv"
df = pd.read_csv('data.csv')
print(df.head())

题目 5:选择题

以下哪个方法可以查看Pandas DataFrame的列名?

A. df.head()

B. df.columns

C. df.tail()

D. df.info()
**B. df.columns**

解析:

  • A. df.head() :显示DataFrame的前5行数据,包含所有列和对应的值,不是专门用于查看列名的方法。

  • B. df.columns :专门用于查看DataFrame的列名,返回一个Index对象,包含所有列名(在示例中为 ['Name', 'Age', 'City', 'Salary'] )。

  • C. df.tail() :显示DataFrame的后5行数据,与head()类似,不是专门用于查看列名的方法。

  • D. df.info() :显示DataFrame的基本信息(如数据类型、非空值数量等),虽然包含列名,但这是综合信息展示,不是专门用于查看列名的方法。

题目 6:简答题

简要说明Pandas中的loc和iloc的区别,并举例说明它们的用法。
`loc`是标签(label)为基础的索引,它接受行和列的标签作为输入。

`iloc`是整数位置(integer position)为基础的索引,它接受行和列的位置作为输入。

题目 7:选择题

在Pandas中,dropna()函数的作用是:

A. 删除DataFrame中的所有数据

B. 删除包含NaN值的行或列

C. 替换NaN值为0

D. 删除DataFrame中的所有重复值
**B. 删除包含NaN值的行或列**

题目 8:编程题

请使用Pandas创建一个包含10个整数的Series,并计算该Series的平均值、最大值和最小值。

提示: 使用mean(), max(), min()等方法。

复制代码
import pandas as pd

# 创建一个包含10个整数的Series
s = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

# 计算平均值、最大值和最小值
mean_val = s.mean()
max_val = s.max()
min_val = s.min()

print("平均值:", mean_val)
print("最大值:", max_val)
print("最小值:", min_val)

题目 9:选择题

以下哪个方法用于向Pandas DataFrame中添加一列数据?

A. df.add_column()

B. df.append_column()

C. df['new_column'] = value

D. df.insert_column()
**C. df['new_column'] = value**

题目 10:编程题

使用Pandas读取一个CSV文件,并选取其中的某一列数据进行排序并输出。假设CSV文件包含名为Name、Age、Salary的列。

提示: 使用sort_values()方法对指定列进行排序。

复制代码
import pandas as pd

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

# 根据Salary列进行排序
sorted_df = df.sort_values(by='Salary')

print(sorted_df)

题目 11:选择题

在Pandas中,如何计算DataFrame某一列的唯一值?

A. df.unique()

B. df.distinct()

C. df.value_counts()

D. df.unique_values()
**A. df.unique()**

题目 12:编程题

使用Pandas读取一个CSV文件,筛选出年龄大于30的所有行,并输出筛选后的数据。

提示: 使用条件筛选来获取符合条件的数据。

复制代码
import pandas as pd

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

# 筛选年龄大于30的所有行
filtered_df = df[df['Age'] > 30]

print(filtered_df)

题目 13:编程题

使用Pandas创建一个DataFrame,包含以下数据:

Name Age City

Alice 25 New York

Bob 30 Boston

Charlie 35 Chicago

并输出该DataFrame。

复制代码
import pandas as pd

# 创建DataFrame
data = {
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [25, 30, 35],
    'City': ['New York', 'Boston', 'Chicago']
}
df = pd.DataFrame(data)

print(df)
相关推荐
余瑜鱼鱼鱼2 小时前
Java数据结构:从入门到精通(十三)
java·开发语言
wzfj123452 小时前
FreeRTOS xTaskCreateStatic 详解
开发语言·c#
kkoral2 小时前
Python 肢体动作追踪项目(基于 MediaPipe + OpenCV)
python·opencv·meidiapipe
运维行者_2 小时前
远程办公场景 NFA:从网络嗅探与局域网流量监控软件排查团队网络卡顿问题
运维·服务器·开发语言·网络·自动化·php
txinyu的博客2 小时前
C++ 智能指针 (shared_ptr/weak_ptr) 全解析
开发语言·c++
没有bug.的程序员2 小时前
Java内存模型(JMM)深度解析:从 volatile 到 happens-before 的底层机制
java·开发语言·并发编程·volatile·内存模型·jmm·happens-before
小徐不徐说2 小时前
避坑指南:Qt 中 Lambda 表达式崩溃原因与高效使用实践
数据库·c++·qt·面试
程序员杰哥2 小时前
2026软件测试面试宝典(含答案+文档)
自动化测试·软件测试·python·测试工具·面试·职场和发展·测试用例
宵时待雨2 小时前
数据结构(初阶)笔记归纳2:顺序表的实现
c语言·数据结构·笔记·算法