首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

力扣pandas每日一题-----持续更新中

  • 25-03-07 17:21
  • 4183
  • 13811
blog.csdn.net

空值处理

dropna()

删除包含空值的行

默认情况下,dropna()会删除包含任何空值的行。

import pandas as pd
import numpy as np
 
# 创建一个包含空值的DataFrame
df = pd.DataFrame({
    'A': [1, np.nan, 3],
    'B': [4, 5, np.nan],
    'C': [7, 8, 9]
})
 
# 删除包含空值的行
df_dropped_rows = df.dropna()
 
print(df_dropped_rows)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

在这个例子中,第二行和第三行都包含空值,但由于默认设置是删除包含空值的任何行,所以这两行都会被删除。然而,由于第三行在’B’列中有空值,而第二行在’A’列中有空值,且没有其他行在所有列中都非空,因此结果将是一个空DataFrame(在这个特定例子中)。

如果你想要删除包含空值的特定列的行,你可以使用subset参数。

# 只考虑'A'列和'B'列中的空值来删除行
df_dropped_rows_subset = df.dropna(subset=['A', 'B'])
 
print(df_dropped_rows_subset)
  • 1
  • 2
  • 3
  • 4

在这个修改后的例子中,只有第二行会因为’A’列中的空值而被删除。

删除包含空值的列

如果你想删除包含空值的列,你需要将axis参数设置为1(或'columns')。

# 删除包含空值的列
df_dropped_columns = df.dropna(axis=1)
 
print(df_dropped_columns)
  • 1
  • 2
  • 3
  • 4

在这个例子中,'B’列会被删除,因为它包含空值。

设置删除空值的阈值

你可以使用thresh参数来指定一个阈值,只有当行或列中的非空值数量少于这个阈值时,才会被删除。

# 删除非空值少于2个的行
df_dropped_rows_thresh = df.dropna(thresh=2)
 
print(df_dropped_rows_thresh)
  • 1
  • 2
  • 3
  • 4

在这个例子中,第二行会被删除,因为它只有1个非空值。

防止就地修改

与drop()方法类似,dropna()默认返回一个新的DataFrame,而不会修改原始DataFrame。如果你希望直接修改原始DataFrame,可以使用inplace=True参数。

df.dropna(inplace=True)
print(df)  # 此时,原始DataFrame已被修改
  • 1
  • 2

fillna()

在Pandas中,fillna 方法用于填充 DataFrame 或 Series 中的缺失值(即 NaN 值)。它提供了多种选项来指定要填充的值或方法。以下是一些常用的用法示例:

基本用法

用单个值填充
import pandas as pd
import numpy as np
 
# 创建一个包含 NaN 值的 DataFrame
df = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [np.nan, 2, 3, 4],
    'C': [1, np.nan, np.nan, 4]
})
 
# 用单个值填充所有 NaN
df_filled = df.fillna(0)
print(df_filled)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
用不同的值填充不同列

1158. 市场分析 I

# 用字典指定每列要填充的值
df_filled_diff = df.fillna({'A': 0, 'B': 1, 'C': 2})
print(df_filled_diff)
  • 1
  • 2
  • 3
用前一个有效值填充(前向填充)
# 使用前一个有效值填充
df_filled_ffill = df.fillna(method='ffill')
print(df_filled_ffill)
  • 1
  • 2
  • 3
用后一个有效值填充(后向填充)
# 使用后一个有效值填充
df_filled_bfill = df.fillna(method='bfill')
print(df_filled_bfill)
  • 1
  • 2
  • 3
用列的均值填充
# 使用列的均值填充 NaN 值
df_filled_mean = df.fillna(df.mean())
print(df_filled_mean)
  • 1
  • 2
  • 3
用插值法填充
# 使用插值法填充(线性插值)
df_filled_interpolate = df.interpolate()
print(df_filled_interpolate)
  • 1
  • 2
  • 3

注意事项

  • fillna 方法返回一个新的 DataFrame 或 Series,不会修改原始数据。
  • 可以使用 inplace=True 参数直接修改原始数据,例如 df.fillna(0, inplace=True)。
  • method='ffill' 和 method='bfill' 分别对应于前向填充和后向填充,适用于时间序列数据。
  • 插值法(interpolate)通常用于处理时间序列数据中的缺失值。

判断DataFrame为空

检查形状(shape)

通过检查 DataFrame 的形状(即行数和列数),可以判断它是否为空。如果行数为0或列数为0,则可以认为它是空的。

import pandas as pd
 
# 创建一个空的 DataFrame
df = pd.DataFrame()
 
# 判断 DataFrame 是否为空
if df.shape[0] == 0 or df.shape[1] == 0:
    print("DataFrame is empty")
else:
    print("DataFrame is not empty")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

使用 empty 属性

Pandas 的 DataFrame 对象有一个 empty 属性,它直接返回一个布尔值,指示 DataFrame 是否为空(即没有任何行)。注意,这个属性只检查行数,不检查列数。因此,如果一个 DataFrame 有列但没有行,它仍然会被认为是空的。

import pandas as pd
 
# 创建一个空的 DataFrame
df = pd.DataFrame()
 
# 判断 DataFrame 是否为空
if df.empty:
    print("DataFrame is empty")
else:
    print("DataFrame is not empty")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

结合使用 shape 和 empty

如果你希望更严格地检查 DataFrame 是否既没有行也没有列,可以结合使用 shape 和 empty 属性。

import pandas as pd
 
# 创建一个空的 DataFrame
df = pd.DataFrame()
 
# 判断 DataFrame 是否为空(既没有行也没有列)
if df.empty and df.shape[1] == 0:
    print("DataFrame is completely empty (no rows and no columns)")
else:
    print("DataFrame is not completely empty")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

检查数据内容

586. 订单最多的客户

在某些情况下,你可能还需要检查 DataFrame 中的数据内容是否为 NaN 或其他特定值。不过,这通常用于更复杂的场景,而不是简单地判断 DataFrame 是否为空。

import pandas as pd
import numpy as np
 
# 创建一个全是 NaN 的 DataFrame
df = pd.DataFrame(np.nan, index=[0], columns=[0])
 
# 判断 DataFrame 是否真正“内容为空”(即所有值都是 NaN)
if df.isnull().values.all():
    print("DataFrame has no non-NaN values")
else:
    print("DataFrame has non-NaN values")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

重复值

duplicated()

在 Pandas 中,duplicated() 是一个非常实用的方法,用于标识重复的行。它返回一个布尔值的 Series,标识哪些行是重复的,默认情况下标识除了第一次出现的所有重复行。

duplicated() 方法的基本用法:

DataFrame.duplicated(subset=None, keep='first')
  • 1

参数说明:

  • subset:用于判断重复的列。如果没有指定,默认会检查所有列。

  • keep

    :控制哪一条记录被标记为重复:

    • 'first'(默认):标记除了第一次出现的记录外,其他重复的行。
    • 'last':标记除了最后一次出现的记录外,其他重复的行。
    • False:标记所有重复的行(包括第一次和最后一次)。

返回值:

duplicated() 返回一个布尔类型的 Series,标记哪些行是重复的。True 表示该行是重复的,False 表示该行是第一次出现。


例子:

假设有一个包含重复数据的 DataFrame:

import pandas as pd

# 示例数据
data = {
    'id': [1, 2, 2, 3, 4, 4, 5],
    'name': ['Alice', 'Bob', 'Bob', 'Charlie', 'David', 'David', 'Eve'],
    'age': [25, 30, 30, 35, 40, 40, 45]
}

df = pd.DataFrame(data)

print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

输出:

id     name  age
0   1    Alice   25
1   2      Bob   30
2   2      Bob   30
3   3  Charlie   35
4   4    David   40
5   4    David   40
6   5      Eve   45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
示例 1:标记重复的行(默认 keep='first')
# 使用 duplicated() 查找重复的行
duplicates = df.duplicated()

print(duplicates)
  • 1
  • 2
  • 3
  • 4

输出:

0    False
1    False
2     True
3    False
4    False
5     True
6    False
dtype: bool
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 解释:duplicated() 会标记除第一次出现的记录之外的所有重复记录。返回的布尔值 Series 表示哪些行是重复的,True 表示是重复的行,False 表示是第一次出现的行。
  • 例如,id=2 和 id=4 的行是重复的,所以下标为 2 和 5 的行会被标记为 True。
示例 2:标记最后一次出现的重复记录(keep='last')
# 使用 duplicated() 查找重复的行,但保留最后一次出现的记录
duplicates_last = df.duplicated(keep='last')

print(duplicates_last)
  • 1
  • 2
  • 3
  • 4

输出:

0    False
1    False
2     True
3    False
4    False
5     True
6    False
dtype: bool
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 解释:keep='last' 时,duplicated() 会标记除了最后一次出现的记录外,其他重复记录为 True。所以,id=2 和 id=4 的第二次出现会被标记为 True,而第一次出现会标记为 False。
示例 3:标记所有重复记录(keep=False)

585. 2016年的投资

619. 只出现一次的最大数字

# 使用 duplicated() 查找所有的重复行,包括第一次和最后一次
duplicates_all = df.duplicated(keep=False)

print(duplicates_all)
  • 1
  • 2
  • 3
  • 4

输出:

0    False
1     True
2     True
3    False
4     True
5     True
6    False
dtype: bool
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 解释:keep=False 时,duplicated() 会标记所有的重复记录为 True,包括第一次出现的记录。
示例 4:根据特定列判断重复项
# 使用 'id' 列来判断重复
duplicates_subset = df.duplicated(subset=['id'])

print(duplicates_subset)
  • 1
  • 2
  • 3
  • 4

输出:

0    False
1    False
2     True
3    False
4    False
5     True
6    False
dtype: bool
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 解释:subset=['id'] 表示只根据 id 列来判断重复项。id=2 和 id=4 会被标记为重复,第二次出现时标记为 True,第一次出现时标记为 False。
示例 5:删除重复行(基于 duplicated())

你可以使用 duplicated() 来标记重复项,然后结合 DataFrame 的布尔索引删除重复项。例如,要删除所有重复的行,保留第一次出现的记录:

df_no_duplicates = df[~df.duplicated()]

print(df_no_duplicates)
  • 1
  • 2
  • 3

输出:

id     name  age
0   1    Alice   25
1   2      Bob   30
3   3  Charlie   35
4   4    David   40
6   5      Eve   45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 解释:~df.duplicated() 返回的是 duplicated() 布尔 Series 的反向值,~True 是 False,~False 是 True,因此通过 df[~df.duplicated()] 可以保留第一次出现的记录,删除后续的重复行。
示例 6:修改原始 DataFrame(使用 inplace=True)
df.drop_duplicates(inplace=True)

print(df)
  • 1
  • 2
  • 3
  • 解释:drop_duplicates() 会修改原始的 DataFrame,删除重复行。

总结:

  • duplicated() 方法用于标记重复行,返回一个布尔值 Series,表示哪些行是重复的。

  • keep
    
    • 1

    参数可以控制保留哪一条记录:

    • 'first'(默认):标记除了第一次出现的记录外,其他重复行。
    • 'last':标记除了最后一次出现的记录外,其他重复行。
    • False:标记所有重复的行,包括第一次和最后一次出现的行。
  • subset 参数允许你只根据特定的列来判断重复项。

  • 结合 duplicated() 和布尔索引,可以删除重复的行。

drop_duplicates()

在 Pandas 中,drop_duplicates() 是一个非常实用的函数,用于去除重复的行(或列)。它允许你根据特定的列或整个数据框来删除重复项。

drop_duplicates() 方法的基本用法:

DataFrame.drop_duplicates(subset=None, keep='first', inplace=False, ignore_index=False)
  • 1

参数说明:

  • subset:指定哪些列用于判断重复。如果没有指定,默认情况下会根据所有列判断重复。

  • keep

    :决定保留哪一条重复记录:

    • 'first'(默认):保留首次出现的记录,删除后续的重复项。
    • 'last':保留最后一条记录,删除之前的重复项。
    • False:删除所有重复项。
  • inplace:是否在原始数据上进行修改。如果为 True,则会直接修改原始 DataFrame,并返回 None;如果为 False(默认),则返回一个新的 DataFrame。

  • ignore_index:是否重新索引。默认为 False,如果为 True,则会重新排列索引。

例子:

假设有一个包含重复数据的 DataFrame:

import pandas as pd

# 示例数据
data = {
    'id': [1, 2, 2, 3, 4, 4, 5],
    'name': ['Alice', 'Bob', 'Bob', 'Charlie', 'David', 'David', 'Eve'],
    'age': [25, 30, 30, 35, 40, 40, 45]
}

df = pd.DataFrame(data)

print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

输出:

   id     name  age
0   1    Alice   25
1   2      Bob   30
2   2      Bob   30
3   3  Charlie   35
4   4    David   40
5   4    David   40
6   5      Eve   45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
示例 1:去除所有重复的行(基于所有列)
df_no_duplicates = df.drop_duplicates()

print(df_no_duplicates)
  • 1
  • 2
  • 3

输出:

id     name  age
0   1    Alice   25
1   2      Bob   30
3   3  Charlie   35
4   4    David   40
6   5      Eve   45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 解释:默认情况下,drop_duplicates() 会检查所有列的重复项,并删除后面的重复行,只保留第一条出现的记录。
示例 2:根据某一列去重(例如:根据 id 列)
df_no_duplicates = df.drop_duplicates(subset=['id'])

print(df_no_duplicates)
  • 1
  • 2
  • 3

输出:

id     name  age
0   1    Alice   25
1   2      Bob   30
3   3  Charlie   35
4   4    David   40
6   5      Eve   45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 解释:subset=['id'] 表示根据 id 列来检查重复项。重复的 id=2 和 id=4 被删除,只保留每个 id 的第一次出现。
示例 3:保留最后一次出现的重复记录
df_no_duplicates = df.drop_duplicates(subset=['id'], keep='last')

print(df_no_duplicates)
  • 1
  • 2
  • 3

输出:

id     name  age
0   1    Alice   25
2   2      Bob   30
3   3  Charlie   35
5   4    David   40
6   5      Eve   45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 解释:通过 keep='last',我们选择保留重复项中最后一次出现的记录。
示例 4:删除所有重复的行(不保留任何重复项)
df_no_duplicates = df.drop_duplicates(subset=['id'], keep=False)

print(df_no_duplicates)
  • 1
  • 2
  • 3

输出:

id     name  age
0   1    Alice   25
3   3  Charlie   35
6   5      Eve   45
  • 1
  • 2
  • 3
  • 4
  • 解释:keep=False 表示删除所有重复的记录,包括第一次出现的记录。因此,只有没有重复的行被保留下来。
示例 5:修改原始 DataFrame(使用 inplace=True)

511. 游戏玩法分析 I

176. 第二高的薪水

177. 第N高的薪水

df.drop_duplicates(subset=['id'], keep='first', inplace=True)

print(df)
  • 1
  • 2
  • 3

输出:

id     name  age
0   1    Alice   25
1   2      Bob   30
3   3  Charlie   35
4   4    David   40
6   5      Eve   45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 解释:使用 inplace=True 后,drop_duplicates() 会直接在原始 df 上进行修改,而不是返回一个新的 DataFrame。
示例 6:重新索引
df_no_duplicates = df.drop_duplicates(subset=['id'], keep='first', ignore_index=True)

print(df_no_duplicates)
  • 1
  • 2
  • 3

输出:

id     name  age
0   1    Alice   25
1   2      Bob   30
2   3  Charlie   35
3   4    David   40
4   5      Eve   45
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 解释:使用 ignore_index=True 后,删除重复行后会重新排列索引,从 0 开始。

总结:

  • drop_duplicates() 是一个非常实用的方法,可以帮助你快速清理重复的数据。
  • subset 参数允许你根据指定的列来判断是否为重复数据。
  • keep 参数控制保留哪一条记录:'first'(默认)、'last' 或 False(删除所有重复项)。
  • 使用 inplace=True 可以直接修改原始 DataFrame,而不是返回一个新的 DataFrame。

数据融合/拼接

merge()

关键字

  1. left:第一个 DataFrame 对象。

  2. right:第二个 DataFrame 对象。

  3. how:指定合并的方式。默认为 ‘inner’。其他选项包括 ‘left’, ‘right’, ‘outer’。

    • ‘inner’:内连接,只返回两个对象中都存在的键的交集。

    • ‘left’:左连接,返回左对象中的所有键,以及右对象中匹配的键。

      175. 组合两个表

    • ‘right’:右连接,返回右对象中的所有键,以及左对象中匹配的键。

    • ‘outer’:外连接,返回左和右对象中所有的键,匹配不到的键则填充 NaN。

  4. on:要加入的列名。必须在左右 DataFrame 对象中都存在。如果未指定,且未指定 left_on 和 right_on,则 DataFrame 中的列名交集将被作为连接键。

  5. left_on:左 DataFrame 中的列或索引级别名称用作键。可以是列名、索引名或长度的数组。

    181. 超过经理收入的员工

  6. right_on:右 DataFrame 中的列或索引级别名称用作键。可以是列名、索引名或长度的数组。

  7. left_index:布尔值,默认为 False。如果为 True,则使用左 DataFrame 的索引(行标签)作为其连接键。

  8. right_index:布尔值,默认为 False。如果为 True,则使用右 DataFrame 的索引(行标签)作为其连接键。

  9. sort:布尔值,默认为 False。根据连接键对合并后的数据进行排序。这在合并具有大量数据的大型 DataFrame 时可能会非常耗时。

  10. suffixes:用于追加到重叠列名末尾的元组字符串(默认为 (‘_x’, ‘_y’))。例如,如果两个对象都有 ‘A’ 列,则结果对象将有 ‘A_x’ 和 ‘A_y’ 列。

  11. copy:布尔值,默认为 True。如果为 False,则不复制数据(可能节省内存)。

  12. indicator:布尔值或字符串,默认为 False。如果为 True 或字符串,将向输出 DataFrame 添加一个特殊列 ‘_merge’,以指示每行数据的来源:‘left_only’、‘right_only’ 或 ‘both’。如果为字符串,则将该字符串用作列名。

  13. validate:检查合并键是否在左右 DataFrame 对象中指定为列名。可以是 ‘one_to_one’, ‘one_to_many’, ‘many_to_one’, ‘many_to_many’ 之一。仅在合并键在 DataFrame 中明确指定时才有意义(即使用 on、left_on 或 right_on 参数)。

示例1:内连接(Inner Join)

import pandas as pd
 
# 创建两个示例DataFrame
df1 = pd.DataFrame({
    'key': ['A', 'B', 'C', 'D'],
    'value1': [1, 2, 3, 4]
})
 
df2 = pd.DataFrame({
    'key': ['A', 'B', 'E', 'F'],
    'value2': [5, 6, 7, 8]
})
 
# 内连接
merged_inner = pd.merge(df1, df2, on='key', how='inner')
print(merged_inner)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

输出:

key  value1  value2
0   A       1       5
1   B       2       6
  • 1
  • 2
  • 3

示例2:左连接(Left Join)

577. 员工奖金

# 左连接
merged_left = pd.merge(df1, df2, on='key', how='left')
print(merged_left)
  • 1
  • 2
  • 3

输出:

key  value1  value2
0   A       1     5.0
1   B       2     6.0
2   C       3     NaN
3   D       4     NaN
  • 1
  • 2
  • 3
  • 4
  • 5

示例3:右连接(Right Join)

# 右连接
merged_right = pd.merge(df1, df2, on='key', how='right')
print(merged_right)
  • 1
  • 2
  • 3

输出:

key  value1  value2
0   A     1.0       5
1   B     2.0       6
2   E     NaN       7
3   F     NaN       8
  • 1
  • 2
  • 3
  • 4
  • 5

示例4:外连接(Outer Join)

# 外连接
merged_outer = pd.merge(df1, df2, on='key', how='outer')
print(merged_outer)
  • 1
  • 2
  • 3

输出:

key  value1  value2
0   A     1.0     5.0
1   B     2.0     6.0
2   C     3.0     NaN
3   D     4.0     NaN
4   E     NaN     7.0
5   F     NaN     8.0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

示例5:使用left_on和right_on参数

# 创建两个示例DataFrame,其中用于合并的列名不同
df3 = pd.DataFrame({
    'lkey': ['A', 'B', 'C'],
    'lvalue': [10, 20, 30]
})
 
df4 = pd.DataFrame({
    'rkey': ['A', 'B', 'D'],
    'rvalue': [40, 50, 60]
})
 
# 使用left_on和right_on参数进行合并
merged_custom_keys = pd.merge(df3, df4, left_on='lkey', right_on='rkey', how='inner')
print(merged_custom_keys)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

输出:

lkey  lvalue rkey  rvalue
0    A      10    A      40
1    B      20    B      50
  • 1
  • 2
  • 3

示例6:使用suffixes参数

# 创建两个示例DataFrame,其中有一列名称相同
df5 = pd.DataFrame({
    'key': ['X', 'Y', 'Z'],
    'value': [100, 200, 300]
})
 
df6 = pd.DataFrame({
    'key': ['X', 'Y', 'W'],
    'value': [400, 500, 600]
})
 
# 使用suffixes参数为相同名称的列添加后缀
merged_suffixes = pd.merge(df5, df6, on='key', suffixes=('_left', '_right'), how='inner')
print(merged_suffixes)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

输出:

key  value_left  value_right
0   X         100          400
1   Y         200          500
  • 1
  • 2
  • 3

这些示例展示了如何使用pandas.merge()函数进行不同类型的数据合并,包括内连接、左连接、右连接、外连接,以及如何处理不同名称的合并键和相同名称的列。

concat()

在Pandas中,concat函数是一个非常强大的工具,用于将多个pandas对象(如DataFrame或Series)沿着指定轴拼接在一起。这个函数非常灵活,允许你沿着行(axis=0,默认)或列(axis=1)进行拼接,并且可以通过多种方式处理索引和列标签。

以下是pd.concat函数的一些关键参数和用法示例:

关键参数

  • objs:要拼接的对象列表或字典。列表中的元素可以是DataFrame、Series或其他pandas对象。如果是字典,则字典的键会被用作结果的列名或行索引。
  • axis:拼接的轴。0表示沿着行拼接(纵向),1表示沿着列拼接(横向)。默认值为0。
  • join:指定如何处理索引。‘outer’(默认)表示取并集,'inner’表示取交集。
  • ignore_index:如果为True,则不保留原有的索引,而是生成一个新的整数索引。
  • keys:用于添加多级索引(层次化索引)。这个参数通常与字典一起使用。
  • levels:用于多级索引(层次化索引)的级别名称。
  • names:多级索引(层次化索引)的名称。
  • verify_integrity:如果为True,则在拼接时检查新生成的DataFrame的索引/列是否有重复。这有助于捕捉潜在的错误。

用法示例

1. 沿着行拼接两个DataFrame
import pandas as pd
 
df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
df2 = pd.DataFrame({'A': ['A2', 'A3'], 'B': ['B2', 'B3']})
 
result = pd.concat([df1, df2], axis=0)
print(result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
2. 沿着列拼接两个DataFrame
df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
df2 = pd.DataFrame({'C': ['C0', 'C1'], 'D': ['D0', 'D1']})
 
result = pd.concat([df1, df2], axis=1)
print(result)
  • 1
  • 2
  • 3
  • 4
  • 5
3. 使用字典拼接,并添加多级索引
df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']})
df2 = pd.DataFrame({'A': ['A2', 'A3'], 'B': ['B2', 'B3']})
 
result = pd.concat({'key1': df1, 'key2': df2}, axis=0, keys=['group1', 'group2'])
print(result)
  • 1
  • 2
  • 3
  • 4
  • 5

在这个例子中,我们使用了keys参数来添加一个新的层次化索引,使得结果DataFrame有两个索引级别:一个是我们指定的键(‘group1’和’group2’),另一个是原有的索引。

4. 忽略原有索引,生成新的整数索引
df1 = pd.DataFrame({'A': ['A0', 'A1'], 'B': ['B0', 'B1']}, index=[1, 2])
df2 = pd.DataFrame({'A': ['A2', 'A3'], 'B': ['B2', 'B3']}, index=[3, 4])
 
result = pd.concat([df1, df2], axis=0, ignore_index=True)
print(result)
  • 1
  • 2
  • 3
  • 4
  • 5

在这个例子中,ignore_index=True使得结果DataFrame使用了新的从0开始的整数索引。

顺序错乱值

sort_values()

在pandas中,sort_values()是一个用于对DataFrame或Series按指定列进行排序的方法。它允许你按升序或降序排列数据。

用法

DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last', ignore_index=False)
  • 1

参数说明

  • by: 用于排序的列名称或列名的列表。对于DataFrame,这是你希望依据其值来排序的列。
  • axis: 默认值为0,表示按行排序。如果为1,表示按列排序。
  • ascending: 布尔值或布尔值列表,默认为True,表示按升序排序。如果为False,则按降序排序。如果是一个列表,长度应与by的长度相同,用于不同列的排序顺序。
  • inplace: 默认为False,表示返回一个新的排序后的DataFrame,如果设为True,则原地修改,不返回新对象。
  • kind: 排序算法,支持'quicksort'(快速排序)、'mergesort'(归并排序)和'heapsort'(堆排序)。默认为'quicksort'。
  • na_position: 默认为'last',表示缺失值排在最后。如果设为'first',缺失值将排在最前面。
  • ignore_index: 默认为False,表示保留原来的索引。如果设为True,返回排序后的结果时,重新生成索引。

示例

176. 第二高的薪水

177. 第N高的薪水

620. 有趣的电影

1. 按单列排序
import pandas as pd

df = pd.DataFrame({
    'A': [3, 1, 4, 2],
    'B': [7, 8, 5, 6]
})

# 按列 'A' 升序排序
df_sorted = df.sort_values(by='A')
print(df_sorted)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

输出:

   A  B
1  1  8
3  2  6
0  3  7
2  4  5
  • 1
  • 2
  • 3
  • 4
  • 5
2. 按多列排序
# 按 'A' 升序,'B' 降序排序
df_sorted = df.sort_values(by=['A', 'B'], ascending=[True, False])
print(df_sorted)
  • 1
  • 2
  • 3

输出:

   A  B
1  1  8
3  2  6
0  3  7
2  4  5
  • 1
  • 2
  • 3
  • 4
  • 5
3. 原地排序(不返回新的DataFrame)
df.sort_values(by='A', inplace=True)
print(df)
  • 1
  • 2

输出:

   A  B
1  1  8
3  2  6
0  3  7
2  4  5
  • 1
  • 2
  • 3
  • 4
  • 5
4. 排序时处理缺失值
df_with_nan = pd.DataFrame({
    'A': [3, 1, 4, None],
    'B': [7, 8, None, 6]
})

# 按 'A' 升序排序,缺失值排在最后
df_sorted = df_with_nan.sort_values(by='A', na_position='last')
print(df_sorted)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

输出:

	A    B
1  1.0  8.0
0  3.0  7.0
2  4.0  NaN
3  NaN  6.0
  • 1
  • 2
  • 3
  • 4
  • 5

注意

  • sort_values()是对数据进行排序并返回排序后的数据,而不改变原始的DataFrame(除非inplace=True)。
  • 对于Series,sort_values()可以直接作用在数据上。

sort_index()

在pandas中,sort_index()是一个用于根据行或列的索引对DataFrame或Series进行排序的方法。它的主要作用是按照索引的顺序对数据进行排序,而不是按照数据的值进行排序。

用法

DataFrame.sort_index(axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last', ignore_index=False)
  • 1

参数说明

  • axis: 默认为0,表示按照行索引进行排序。如果为1,则表示按列索引排序。
  • ascending: 布尔值或布尔值列表,默认True。表示是否按升序排序。如果为False,则按降序排序。如果是一个列表,长度应该和索引的数量一致,用于不同索引的排序顺序。
  • inplace: 默认为False,表示返回一个排序后的DataFrame。如果设为True,则对原始数据进行排序,不返回新对象。
  • kind: 排序算法,支持'quicksort'(快速排序)、'mergesort'(归并排序)和'heapsort'(堆排序)。默认为'quicksort'。
  • na_position: 默认为'last',表示缺失值排在最后。如果设为'first',缺失值会排在最前面。
  • ignore_index: 默认为False,表示保留原有的索引。如果设为True,会重新生成索引。

示例

1. 按行索引排序
import pandas as pd

df = pd.DataFrame({
    'A': [3, 1, 4, 2],
    'B': [7, 8, 5, 6]
}, index=['d', 'a', 'c', 'b'])

# 按行索引升序排序
df_sorted = df.sort_index()
print(df_sorted)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

输出:

   A  B
a  1  8
b  2  6
c  4  5
d  3  7
  • 1
  • 2
  • 3
  • 4
  • 5
2. 按列索引排序
# 按列索引升序排序
df_sorted = df.sort_index(axis=1)
print(df_sorted)
  • 1
  • 2
  • 3

输出:

   A  B
d  3  7
a  1  8
c  4  5
b  2  6
  • 1
  • 2
  • 3
  • 4
  • 5
3. 降序排序索引
# 按行索引降序排序
df_sorted = df.sort_index(ascending=False)
print(df_sorted)
  • 1
  • 2
  • 3

输出:

   A  B
d  3  7
c  4  5
b  2  6
a  1  8
  • 1
  • 2
  • 3
  • 4
  • 5
4. 原地排序(不返回新的DataFrame)
df.sort_index(inplace=True)
print(df)
  • 1
  • 2

输出:

   A  B
a  1  8
b  2  6
c  4  5
d  3  7
  • 1
  • 2
  • 3
  • 4
  • 5
5. 排序时处理缺失值
df_with_nan = pd.DataFrame({
    'A': [3, 1, 4, None],
    'B': [7, 8, None, 6]
}, index=['d', 'a', 'c', 'b'])

# 按行索引排序,并将缺失值放到最后
df_sorted = df_with_nan.sort_index(na_position='last')
print(df_sorted)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

输出:

     A    B
a  1.0  8.0
b  NaN  6.0
c  4.0  NaN
d  3.0  7.0
  • 1
  • 2
  • 3
  • 4
  • 5
6. 忽略原有索引,重新生成索引
# 忽略原有索引,重新生成索引
df_sorted = df_with_nan.sort_index(ignore_index=True)
print(df_sorted)
  • 1
  • 2
  • 3

输出:

     A    B
0  1.0  8.0
1  NaN  6.0
2  4.0  NaN
3  3.0  7.0
  • 1
  • 2
  • 3
  • 4
  • 5

总结

  • sort_index() 主要是根据索引进行排序,而不是根据数据本身的值。
  • 可以选择按行索引或列索引进行排序,支持升序和降序排列。
  • 通过设置inplace=True,可以原地修改DataFrame。
  • 处理缺失值时,可以使用na_position来决定缺失值的位置。

rank()

在 pandas 中,rank() 方法用于对 DataFrame 或 Series 中的数值进行排名。根据所提供的参数,可以控制排名的计算方式,支持多种排名方法,如 升序 或 降序,以及 相同值的排名 方式。

基本用法

DataFrame.rank(axis=0, method='average', ascending=True, na_option='keep', numeric_only=False, pct=False)
  • 1

参数解释

  • axis: 默认为 0,表示对行进行排名。如果为 1,则对列进行排名。

  • method
    排名方法。可选值有:
    • 'average': 相同数值的平均排名(默认)。
    • 'min': 相同数值的最小排名。
    • 'max': 相同数值的最大排名。
    • 'first': 按照原始顺序进行排名,遇到相同数值时,先出现的排前面。
    • 'dense': 稠密排名,相同数值的排名相同,接下来的排名没有空缺。
  • ascending: 布尔值,默认为 True,表示升序排序。如果为 False,则按降序排序。

  • na_option: 控制缺失值的处理方式。可选值为 'keep'、'top'、'bottom'。默认为 'keep',即保留缺失值不参与排名。 'top' 和 'bottom' 分别表示将缺失值排在前面或最后。

  • numeric_only: 默认为 False,表示包括所有类型的列进行排名。如果为 True,则仅考虑数值类型的列。

  • pct: 默认为 False,表示返回的排名为整数。如果为 True,返回的排名是比例值(百分比形式)。

示例

1. 基本排名(默认 average)
import pandas as pd

data = {'score': [3.5, 4.0, 3.65, 3.85, 4.0, 3.65]}
df = pd.DataFrame(data)

df['rank'] = df['score'].rank()
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

输出:

   score  rank
0   3.50   4.0
1   4.00   1.5
2   3.65   3.5
3   3.85   2.0
4   4.00   1.5
5   3.65   3.5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

解释:

  • 使用 average 排名方法,相同的分数(如 4.0 和 3.65)的排名为相同的平均值。例如,4.0 出现了两次,所以它们的排名是 1.5。
2. 使用 min 排名方法

1070. 产品销售分析 III

df['rank_min'] = df['score'].rank(method='min')
print(df)
  • 1
  • 2

输出:

   score  rank  rank_min
0   3.50   4.0       4.0
1   4.00   1.5       1.0
2   3.65   3.5       3.0
3   3.85   2.0       2.0
4   4.00   1.5       1.0
5   3.65   3.5       3.0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

解释:

  • 使用 min 方法时,所有相同的分数都获得最小排名。例如,4.0 的排名是 1,3.65 的排名是 3,即便它们出现多次。
3. 使用 dense 排名方法

178. 分数排名

df['rank_dense'] = df['score'].rank(method='dense')
print(df)
  • 1
  • 2

输出:

   score  rank  rank_min  rank_dense
0   3.50   4.0       4.0         4.0
1   4.00   1.5       1.0         1.0
2   3.65   3.5       3.0         3.0
3   3.85   2.0       2.0         2.0
4   4.00   1.5       1.0         1.0
5   3.65   3.5       3.0         3.0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

解释:

  • dense 方法给相同的分数相同的排名,并且排名没有跳跃。例如,两个分数相同(如 4.0 和 3.65)的排名相同,但接下来的排名没有空缺。
4. 排名方法 first
df['rank_first'] = df['score'].rank(method='first')
print(df)
  • 1
  • 2

输出:

   score  rank  rank_min  rank_dense  rank_first
0   3.50   4.0       4.0         4.0         4.0
1   4.00   1.5       1.0         1.0         1.0
2   3.65   3.5       3.0         3.0         3.0
3   3.85   2.0       2.0         2.0         2.0
4   4.00   1.5       1.0         1.0         1.0
5   3.65   3.5       3.0         3.0         3.0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

解释:

  • first 方法按照出现的顺序进行排名。当有相同分数时,先出现的分数获得较小的排名。
5. 排名计算百分比(pct=True)
df['rank_pct'] = df['score'].rank(pct=True)
print(df)
  • 1
  • 2

输出:

   score  rank  rank_min  rank_dense  rank_first  rank_pct
0   3.50   4.0       4.0         4.0         4.0   0.833333
1   4.00   1.5       1.0         1.0         1.0   0.166667
2   3.65   3.5       3.0         3.0         3.0   0.5
3   3.85   2.0       2.0         2.0         2.0   0.333333
4   4.00   1.5       1.0         1.0         1.0   0.166667
5   3.65   3.5       3.0         3.0         3.0   0.5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

解释:

  • pct=True 返回百分比排名,即每个分数的排名占所有分数的比例。排名越高的分数比例越小,接近 0。

总结

  • rank() 是一个非常灵活的工具,用于根据不同的规则为数据中的每个元素分配排名。
  • 常见的排名方法包括 average(默认)、min、max、dense 和 first,它们决定了相同值的排名如何计算。
  • 可以通过设置 ascending=False 来进行降序排名,pct=True 返回排名的百分比。

数据的移动

shift()

shift() 函数是 Pandas 库中的一个数据处理函数,用于将数据按指定方向移动或偏移。它可以对时间序列数据或其他类型的数据进行操作,通常用于计算时间序列数据的差值、百分比变化等。该函数的主要作用是将数据移动到指定的行或列,留下空白或填充 NaN 值。

shift() 函数的语法
shift() 函数的基本语法如下:

DataFrame.shift(periods=1, freq=None, axis=0, fill_value=None)
参数说明:

  • periods:指定移动的步数,可以为正数(向下移动)或负数(向上移动)。默认为 1。

  • freq:可选参数,用于指定时间序列数据的频率,通常用于时间序列数据的移动操作。

  • axis:指定移动的方向,可以为 0(默认,沿行移动)或 1(沿列移动)。

  • fill_value:可选参数,用于填充移动后留下的空白位置,通常为填充 NaN 值。

shift() 函数的示例
通过一些示例来演示 shift() 函数的用法。

示例 1:向下移动数据

import pandas as pd

data = {'A': [1, 2, 3, 4, 5],
        'B': [10, 20, 30, 40, 50]}
df = pd.DataFrame(data)
  • 1
  • 2
  • 3
  • 4
  • 5

向下移动一行数据

197. 上升的温度

df_shifted = df.shift(periods=1)
print(df_shifted)
输出结果:

A     B
 0  NaN   NaN
1  1.0  10.0
2  2.0  20.0
3  3.0  30.0
4  4.0  40.0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这个示例中,创建了一个包含两列数据的 DataFrame,并使用 shift() 函数向下移动了一行数据。移动后,第一行的数据被填充为 NaN。

示例 2:向上移动数据

import pandas as pd

data = {'A': [1, 2, 3, 4, 5],
        'B': [10, 20, 30, 40, 50]}
df = pd.DataFrame(data)
  • 1
  • 2
  • 3
  • 4
  • 5

向上移动一行数据

df_shifted = df.shift(periods=-1)
print(df_shifted)
输出结果:
    
    A     B
0  2.0  20.0
1  3.0  30.0
2  4.0  40.0
3  5.0  50.0
4  NaN   NaN
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这个示例,使用负数的 periods 参数将数据向上移动了一行。最后一行的数据被填充为 NaN。

示例 3:向右移动列数据

import pandas as pd

data = {'A': [1, 2, 3, 4, 5],
        'B': [10, 20, 30, 40, 50]}
df = pd.DataFrame(data)
  • 1
  • 2
  • 3
  • 4
  • 5

向右移动一列数据

 df_shifted = df.shift(periods=1, axis=1)
print(df_shifted)
输出结果:
 
 A     B
 0  NaN   1.0
1  NaN   2.0
2  NaN   3.0
3  NaN   4.0
4  NaN   5.0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这个示例中,使用 axis=1 参数将列数据向右移动了一列,左边填充为 NaN。

示例 4:指定填充值

import pandas as pd

data = {'A': [1, 

2, 3, 4, 5],
        'B': [10, 20, 30, 40, 50]}
df = pd.DataFrame(data)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

向下移动一行数据,填充空白处为 0

df_shifted = df.shift(periods=1, fill_value=0)
print(df_shifted)
输出结果:

   A   B
0  0   0
1  1  10
2  2  20
3  3  30
4  4  40
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这个示例中,使用 fill_value 参数指定了填充值为 0,因此移动后的空白位置被填充为 0。

日期类型应用

Timedelta()

pandas.Timedelta 是 Pandas 库中的一个类,用于表示时间跨度或持续时间。它通常用于表示两个日期或时间之间的差异,或者进行日期、时间的加减运算。

Timedelta 的常见用途:

  1. 表示时间间隔:例如一天、两小时、三分钟等。
  2. 日期时间运算:例如,计算一个日期与另一个日期的差异,或者将某个时间单位添加到日期上。

Timedelta 组件:

  • days:天数。
  • hours:小时数。
  • minutes:分钟数。
  • seconds:秒数。
  • milliseconds:毫秒数。
  • microseconds:微秒数。
  • nanoseconds:纳秒数。

创建 Timedelta 对象:

你可以通过多种方式创建 Timedelta 对象:

import pandas as pd

# 通过字符串创建 Timedelta
timedelta1 = pd.Timedelta('1 days')  # 1 天
timedelta2 = pd.Timedelta('5 hours')  # 5 小时
timedelta3 = pd.Timedelta('2 minutes')  # 2 分钟

# 通过整数和单位创建 Timedelta
timedelta4 = pd.Timedelta(days=1)  # 1 天
timedelta5 = pd.Timedelta(hours=5)  # 5 小时
timedelta6 = pd.Timedelta(minutes=10)  # 10 分钟

# 通过多个单位创建 Timedelta
timedelta7 = pd.Timedelta(weeks=1, days=2, hours=3, minutes=4)  # 1 周 2 天 3 小时 4 分钟
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

Timedelta 的常见操作:

加减时间:

197. 上升的温度

你可以将 Timedelta 对象加到一个 datetime 对象上,或者从中减去。

# 当前时间
now = pd.to_datetime('2024-01-01')

# 加 5 天
new_date = now + pd.Timedelta(days=5)
print(new_date)  # 输出:2024-01-06

# 减 2 小时
new_time = now - pd.Timedelta(hours=2)
print(new_time)  # 输出:2023-12-31 22:00:00
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
计算两个日期或时间之间的差异:

你可以通过直接相减两个 datetime 对象来计算时间差异,结果是一个 Timedelta 对象。

# 两个时间
date1 = pd.to_datetime('2024-01-01')
date2 = pd.to_datetime('2024-01-06')

# 计算差异
timedelta = date2 - date1
print(timedelta)  # 输出:5 days 00:00:00
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
Timedelta 对象进行运算:
# 创建一个 Timedelta 对象
delta = pd.Timedelta(days=2, hours=3)

# 输出 Timedelta 对象的各个部分
print(delta.days)  # 2
print(delta.seconds)  # 10800 秒(3 小时 = 3 * 3600 秒)
print(delta.total_seconds())  # 177600 秒 (2 天 3 小时的总秒数)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

示例:用 Timedelta 计算前一天日期

如果你想利用 Timedelta 来比较日期并确保日期是连续的(例如,确保没有跳过的日期),你可以用 Timedelta 来加减日期,确保前后日期是连续的。

例如,假设你有一个日期列,并希望找出温度比前一天高的记录。

示例代码:

import pandas as pd

# 示例数据
data = {
    'id': [1, 2],
    'recordDate': ['2000-12-14', '2000-12-16'],
    'temperature': [3, 5]
}

# 创建 DataFrame
df = pd.DataFrame(data)

# 将 'recordDate' 列转换为日期格式并排序
df['recordDate'] = pd.to_datetime(df['recordDate'])
df = df.sort_values('recordDate')

# 获取前一天的温度
df['previous_temperature'] = df['temperature'].shift(1)
df['previous_recordDate'] = df['recordDate'].shift(1)

# 使用 Timedelta 来检查日期是否是前一天
df['is_previous_day'] = df['recordDate'] == (df['previous_recordDate'] + pd.Timedelta(days=1))

# 筛选出温度比前一天高的记录,且日期是连续的(前后日期相差 1 天)
result = df[(df['temperature'] > df['previous_temperature']) & df['is_previous_day']]['id']

# 输出结果
print(result)
  • 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

解释:

  1. 日期转换:将 recordDate 列转换为日期格式,并按日期排序。
  2. 前一天比较:通过 shift(1) 获取前一天的日期和温度。
  3. 日期差检查:用 pd.Timedelta(days=1) 确保前一天的日期是连续的。
  4. 筛选符合条件的结果:确保温度比前一天高,并且日期是连续的。

输出结果:

less



Series([], Name: id, dtype: int64)
  • 1
  • 2
  • 3
  • 4
  • 5

解释:

由于 2000-12-14 和 2000-12-16 之间没有 2000-12-15,所以没有连续的日期,最终返回空结果。

总结:

  • Timedelta 主要用于表示时间差,支持加减运算,并可以方便地进行日期时间之间的比较和计算。
  • 在日期比较时,Timedelta 可以帮助我们确保前后日期是连续的,从而避免出现日期跳跃的问题。

DateOffset()

550. 游戏玩法分析 IV

DateOffset是pandas库中用于处理日期时间偏移量的类。它允许你以不同的时间单位(如天、小时、分钟等)来移动日期时间。

特点:

  • 支持多种时间单位:天、小时、分钟等。
  • 遵循日历规则,适用于处理如工作日、月末等复杂偏移。

使用方法:

  1. 创建一个DateOffset对象,指定偏移的时间单位和数量。
  2. 将DateOffset对象与日期时间相加或相减,实现偏移。

示例:

import pandas as pd
 
# 创建一个日期
date = pd.Timestamp('2023-01-01')
 
# 创建一个DateOffset对象,表示一天的偏移
offset = pd.DateOffset(days=1)
 
# 应用偏移
new_date = date + offset
 
print(new_date)  # 输出:2023-01-02 00:00:00
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

注意事项:

  • 确保时间单位与DateOffset对象的参数相匹配。
  • 处理时区信息时,确保时区正确处理。

frame类型数据更新

在 pandas 中将一条数据更新到一个 DataFrame 中,可以有几种不同的方法,取决于你是要 添加新行 还是 更新已有行。

方法 1: 添加新行

如果你想将一条新数据(新行)添加到 DataFrame 中,可以使用 pd.DataFrame.append() 或 pd.concat() 方法。这两种方法都可以用来将新的数据添加到现有的 DataFrame 中。

示例 1: 使用 append()

假设你有一个现有的 DataFrame 和你要添加的一行数据:

import pandas as pd

# 示例 DataFrame
df = pd.DataFrame({
    'id': [1, 2, 3],
    'num': ['A', 'B', 'C']
})

# 要插入的新行
new_row = {'id': 4, 'num': 'D'}

# 使用 append() 添加新行
df = df.append(new_row, ignore_index=True)

# 打印结果
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

输出:

   id num
0   1   A
1   2   B
2   3   C
3   4   D
  • 1
  • 2
  • 3
  • 4
  • 5

说明:

  • append() 方法会返回一个新的 DataFrame,所以需要将返回结果重新赋值给 df。
  • ignore_index=True 表示重新生成索引。
示例 2: 使用 concat()

concat() 是一种更灵活的方法,也可以用于添加新行。我们可以通过将新的数据转换为一个单行的 DataFrame 并与原 DataFrame 合并来实现。

# 将新行转换为 DataFrame
new_row_df = pd.DataFrame({'id': [4], 'num': ['D']})

# 使用 concat() 添加新行
df = pd.concat([df, new_row_df], ignore_index=True)

# 打印结果
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

输出:

   id num
0   1   A
1   2   B
2   3   C
3   4   D
  • 1
  • 2
  • 3
  • 4
  • 5

方法 2: 更新已有行

如果你要根据某些条件来更新 DataFrame 中的已有行数据,可以直接通过行索引进行更新。例如,假设我们想更新 id 为 2 的行的 num 值。

示例 3: 更新已有行的数据
# 假设我们要更新 id 为 2 的行
df.loc[df['id'] == 2, 'num'] = 'Updated Value'

# 打印结果
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5

输出:

   id            num
0   1              A
1   2  Updated Value
2   3              C
3   4              D
  • 1
  • 2
  • 3
  • 4
  • 5

说明:

  • df.loc[df['id'] == 2, 'num'] 用于选择 id 为 2 的行的 num 列,然后直接将其值更新为 'Updated Value'。

方法 3: 通过索引位置更新

如果你知道要更新的数据行的索引,可以直接通过 iloc[] 来访问并更新该行。

示例 4: 通过索引位置更新数据
# 假设我们要更新索引为 1 的行
df.iloc[1, df.columns.get_loc('num')] = 'Updated Again'

# 打印结果
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5

输出:

   id            num
0   1              A
1   2  Updated Again
2   3              C
3   4              D
  • 1
  • 2
  • 3
  • 4
  • 5

方法 4: 批量更新

如果你需要根据某些条件批量更新多行数据,可以使用 apply() 或 where() 等方法。

示例 5: 使用 apply() 批量更新

# 假设我们根据 'id' 列的值来更新 'num' 列
df['num'] = df['id'].apply(lambda x: 'Updated' if x == 2 else 'Not Updated')

# 打印结果
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5

输出:

   id         num
0   1  Not Updated
1   2     Updated
2   3  Not Updated
3   4  Not Updated
  • 1
  • 2
  • 3
  • 4
  • 5

示例 6: 使用 update() 批量更新

DataFrame.update() 方法的作用是用另一个 DataFrame 或 Series 来更新当前 DataFrame 中的值。更新时,源数据(other)的索引和列索引会与目标数据进行对比,如果匹配,则更新目标数据的对应位置。

update() 方法的参数
  • other:另一个 DataFrame 或 Series,用于提供要更新的值。

  • join控制如何对齐索引和列。可以是 'left'、'right'、'outer' 或 'inner',默认是 'left'。

    'left':使用 other 中的索引和列进行更新(保留目标 DataFrame 的索引和列)。

    'right':使用目标 DataFrame 中的索引和列进行更新。

    'outer':合并两个 DataFrame 的所有索引和列,任何一个 DataFrame 中缺失的部分将填充 NaN。

    'inner':只使用两个 DataFrame 中都有的索引和列。

  • overwrite:布尔值,默认是 True。如果为 True,则将目标 DataFrame 中的所有值都更新为源 DataFrame 中的对应值。否则,只会更新那些原数据中为 NaN 的位置。

update() 示例
示例 1:基本使用
import pandas as pd

# 原始 DataFrame
df1 = pd.DataFrame({
    'A': [1, 2, 3, 4],
    'B': [5, 6, 7, 8],
    'C': [9, 10, 11, 12]
})

# 更新数据的 DataFrame
df2 = pd.DataFrame({
    'A': [10, 20],
    'B': [50, 60],
    'C': [15, 25]
}, index=[1, 2])

# 使用 update() 更新 df1
df1.update(df2)

print(df1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

输出:

    A   B   C
0   1   5   9
1  20  50  15
2  20  60  25
3   4   8  12
  • 1
  • 2
  • 3
  • 4
  • 5

说明:

  • 在 df1 中,索引为 1 和 2 的行被 df2 中相应的值替换了。
  • df1 中其他位置的值(如索引为 0 和 3 的行)没有被 df2 中的任何值更新,因为 df2 中没有这些位置的数据。
示例 2:使用 join 参数

通过 join 参数,可以控制如何对齐索引和列。如果 join='left',那么将保留 df1 的索引,并使用 df2 中的值进行更新。

df1.update(df2, join='left')
print(df1)
  • 1
  • 2

输出:

    A   B   C
0   1   5   9
1  20  50  15
2  20  60  25
3   4   8  12
  • 1
  • 2
  • 3
  • 4
  • 5
示例 3:使用 overwrite=False

如果你不希望更新已经存在值的单元格,而只更新 NaN 值,可以将 overwrite=False:

df1 = pd.DataFrame({
    'A': [1, 2, 3, 4],
    'B': [5, 6, 7, 8],
    'C': [None, 10, None, 12]
})

df2 = pd.DataFrame({
    'A': [10, 20],
    'B': [50, 60],
    'C': [15, 25]
}, index=[1, 2])

# 使用 update() 更新 df1,但不覆盖已存在的非 NaN 值
df1.update(df2, overwrite=False)

print(df1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

输出:

    A   B     C
0   1   5   NaN
1  20  50  15.0
2  20  60  25.0
3   4   8  12.0
  • 1
  • 2
  • 3
  • 4
  • 5

说明:

  • 由于 overwrite=False,df1 中已有的 NaN 值(例如 A[0] 和 C[0])被更新,而已存在的非 NaN 值(例如 C[3])没有被替换。
示例 4:update() 与 join='outer' 使用
df1 = pd.DataFrame({
    'A': [1, 2],
    'B': [3, 4]
}, index=[0, 1])

df2 = pd.DataFrame({
    'A': [5, 6],
    'C': [7, 8]
}, index=[1, 2])

# 使用 'outer' join,合并 df1 和 df2 的所有索引和列
df1.update(df2, join='outer')

print(df1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

输出:

     A    B    C
0  1.0  3.0  NaN
1  6.0  4.0  8.0
2  NaN  NaN  7.0
  • 1
  • 2
  • 3
  • 4

说明:

  • 使用 join='outer' 时,df1 中所有索引和列都会与 df2 的索引和列合并。df2 中没有的值将填充为 NaN。
update() 的优缺点

优点:

  • update() 方法直接修改原始 DataFrame,它不会创建新的 DataFrame,因此可以节省内存。
  • 可以灵活地控制更新行为,通过 join 和 overwrite 参数,可以适应不同的需求。

缺点:

  • update() 仅会替换原始 DataFrame 中对应索引和列的部分。如果 df2 中的某些行列不在 df1 中,它们不会影响 df1。
  • 无法直接应用复杂的自定义操作(如根据条件更新),这时可能需要用其他方法(如 apply())来实现。

总结

  • 添加新行:可以使用 append() 或 concat() 方法。
  • 更新已有行:可以通过 loc[] 或 iloc[] 进行条件更新或按索引位置更新。
  • 批量更新:使用 apply()、where() 或其他条件逻辑进行批量更新。
  • **update()**方法主要用于根据另一个 DataFrame 更新当前 DataFrame,并且具有灵活的参数来控制如何处理索引和更新规则。

固定窗口移动

rolling()

# Pandas `rolling` 方法总结

`rolling` 是 Pandas 中用于进行滑动窗口操作的函数,可以用于时间序列数据的聚合、平滑等操作。常见的聚合操作包括均值、和、标准差等,还可以与其他函数结合使用以实现更复杂的计算。

## 1. 基本用法

通过 `rolling(window)` 创建一个滑动窗口,`window` 表示窗口大小。

### 示例:

```
import pandas as pd

data = pd.Series([1, 2, 3, 4, 5, 6, 7, 8, 9])

# 计算每个窗口的均值
rolling_mean = data.rolling(window=3).mean()

print(rolling_mean)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

输出:

0    NaN
1    NaN
2    2.0
3    3.0
4    4.0
5    5.0
6    6.0
7    7.0
8    8.0
dtype: float64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

常见的聚合操作

与 agg() 结合使用

agg() 允许在滑动窗口中使用多个聚合函数。

rolling_agg = data.rolling(window=3).agg(['sum', 'mean', 'std'])
  • 1

与 apply() 结合使用

180. 连续出现的数字

apply() 可以对每个窗口应用自定义的函数。

rolling_apply = data.rolling(window=3).apply(lambda x: x.max() - x.min())
  • 1

与 shift() 结合使用

shift() 用于计算窗口之间的差异,通常用于滞后比较。

rolling_mean = data.rolling(window=3).mean()
rolling_diff = rolling_mean - rolling_mean.shift(1)
  • 1
  • 2

与 min() 和 max() 结合使用

min() 和 max() 计算窗口内的最小值和最大值。

rolling_min = data.rolling(window=3).min()
rolling_max = data.rolling(window=3).max()
  • 1
  • 2

与 corr() 和 cov() 结合使用

corr() 和 cov() 用于计算两个时间序列之间的相关性或协方差。

rolling_corr = data1.rolling(window=3).corr(data2)
  • 1

与 cum*() 结合使用

cummin()、cummax()、cumsum() 等方法用于计算窗口的累计统计量。

rolling_cumsum = data.rolling(window=3).cumsum()
  • 1

与 expanding() 结合使用

expanding() 创建一个从数据开始到当前位置的滑动窗口,用于计算累计值。

expanding_sum = data.expanding().sum()
  • 1

常用参数

  • window: 窗口大小,表示每个滑动窗口包含的数据量。
  • min_periods: 窗口内至少需要多少个有效数据才能进行计算,默认值为 None。
  • center: 默认为 False,表示窗口右对齐。如果设置为 True,窗口会以当前数据点为中心进行计算。

示例:

rolling_data = data.rolling(window=3, min_periods=2).mean()
  • 1

总结

rolling 是 Pandas 中一个非常强大的工具,能够方便地对时间序列数据进行窗口聚合计算。与其他函数结合使用时,rolling 可以帮助我们实现更复杂的分析任务,适用于金融、工程、科学等多个领域的数据处理。

常用的组合方法包括:

  • agg(): 多聚合函数应用。
  • apply(): 自定义计算。
  • shift(): 滞后操作。
  • min(), max(): 窗口的最小值、最大值。
  • corr(), cov(): 计算相关性和协方差。
  • cum*(): 累积统计。
  • expanding(): 扩展窗口的累计统计。

分组聚合

groupby()

586. 订单最多的客户

基本用法

  • 分组:通过指定一个或多个列名作为键来对数据进行分组。
  • 聚合:对每个分组应用聚合函数,如求和(sum())、平均值(mean())、最大值(max())、最小值(min())等。
  • 重置索引:分组操作会改变DataFrame的索引,通常你会想要使用 reset_index() 方法来重置索引,使其成为一个普通的列。

示例

单键分组
import pandas as pd
 
# 创建一个简单的DataFrame
df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A'],
    'Values': [10, 20, 30, 40, 50]
})
 
# 根据'Category'列进行分组,并计算每个组的和
grouped = df.groupby('Category')['Values'].sum().reset_index()
 
print(grouped)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这个例子中,数据被分为两组:‘A’ 和 ‘B’,然后计算了每个组的’Values’列的和。

多键分组

1050. 合作过至少三次的演员和导演

# 创建一个包含多个分类列的DataFrame
df_multi = pd.DataFrame({
    'Category1': ['X', 'X', 'Y', 'Y'],
    'Category2': ['A', 'B', 'A', 'B'],
    'Values': [1, 2, 3, 4]
})
 
# 根据'Category1'和'Category2'列进行分组,并计算每个组的和
grouped_multi = df_multi.groupby(['Category1', 'Category2'])['Values'].sum().reset_index()
 
print(grouped_multi)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在这个例子中,数据被分为四组:(‘X’, ‘A’)、(‘X’, ‘B’)、(‘Y’, ‘A’) 和 (‘Y’, ‘B’),然后计算了每个组的’Values’列的和。

应用多个聚合函数
# 使用agg方法应用多个聚合函数
grouped_agg = df.groupby('Category')['Values'].agg(['sum', 'mean', 'max', 'min']).reset_index()
 
print(grouped_agg)
  • 1
  • 2
  • 3
  • 4

在这个例子中,对每个分组应用了四个聚合函数:求和、平均值、最大值和最小值。

转换和过滤

除了聚合之外,groupby() 还可以与 transform() 方法结合使用来进行数据转换,或者与 filter() 方法结合使用来过滤数据。

# 使用transform方法计算每个组的平均值,并将其作为新列添加到原始DataFrame中
df['Mean'] = df.groupby('Category')['Values'].transform('mean')
 
print(df)
  • 1
  • 2
  • 3
  • 4

在这个例子中,每个组的’Values’列的平均值被计算出来,并作为新列’Mean’添加到了原始DataFrame中。

注意事项

  • 当使用 groupby() 时,确保你理解分组键和聚合函数如何影响你的数据。
  • 聚合操作会改变数据的形状,通常会导致某些行或列的丢失。
  • 如果你的DataFrame很大,groupby() 操作可能会比较耗时,特别是在多键分组或应用复杂聚合函数时。在这种情况下,考虑优化你的代码或使用更高效的数据处理策略。

transform()

184. 部门工资最高的员工

550. 游戏玩法分析 IV

transform用于对组内数据进行转换并返回与原始数据框形状相同的结果。它通常与groupby一起使用,目的是对每个组进行操作后,将结果“广播”到原始数据框中。基本用法如下:

# 对每个组计算'value'列的均值,并将均值返回到原数据框中
df['mean_value'] = df.groupby('group')['value'].transform('mean')
print(df)
  • 1
  • 2
  • 3

结合使用

在实际使用中,groupby和transform可以结合起来,从而对数据进行强大的分组计算。例如,计算每个分组的标准差并将其填充到原数据框中:

# 计算每个组的标准差,并将结果赋给原数据框
df['std_value'] = df.groupby('group')['value'].transform('std')
print(df)
  • 1
  • 2
  • 3

apply()

基本用法

  • 对列应用函数:默认情况下,apply() 方法会对DataFrame的每一列应用函数。如果你想对行应用函数,需要设置 axis=1。
  • 返回值:apply() 方法返回一个新的Series(如果沿着列应用)或DataFrame(如果沿着行应用,且函数返回多个值)。
  • 函数:你可以传递任何可调用对象(如函数、lambda表达式或方法)给 apply()。

示例

对列应用函数

610. 判断三角形

import pandas as pd
 
# 创建一个简单的DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [4, 5, 6],
    'C': [7, 8, 9]
})
 
# 定义一个简单的函数,对每个元素加1
def add_one(x):
    return x + 1
 
# 对每一列应用add_one函数
df_plus_one = df.apply(add_one)
 
print(df_plus_one)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这个例子中,add_one 函数被应用于DataFrame的每一列,每个元素都增加了1。

对行应用函数
# 定义一个函数,计算每行的和
def row_sum(row):
    return row.sum()
 
# 对每一行应用row_sum函数
row_sums = df.apply(row_sum, axis=1)
 
print(row_sums)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在这个例子中,row_sum 函数被应用于DataFrame的每一行,计算每行的和,并返回一个Series。

使用lambda函数

1045. 买下所有产品的客户

# 使用lambda函数对每一列的元素乘以2
df_multiplied = df.apply(lambda x: x * 2)
 
print(df_multiplied)
  • 1
  • 2
  • 3
  • 4

在这个例子中,一个lambda函数被用于将DataFrame中每个元素乘以2。

处理复杂的数据结构

如果你的DataFrame包含复杂的数据结构(如列表或字典),你可以编写更复杂的函数来处理这些数据。

# 创建一个包含列表的DataFrame
df_complex = pd.DataFrame({
    'data': [[1, 2], [3, 4], [5, 6]]
})
 
# 定义一个函数,计算列表中元素的和
def sum_list(lst):
    return sum(lst)
 
# 对'data'列应用sum_list函数
sums = df_complex['data'].apply(sum_list)
 
print(sums)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

在这个例子中,sum_list 函数被用于计算DataFrame中’data’列每个列表元素的和。

注意事项

  • 当对大型DataFrame使用 apply() 时,性能可能会受到影响,因为Pandas需要将数据逐行或逐列传递给Python函数。在可能的情况下,优先考虑使用Pandas的内置向量化操作来提高性能。
  • 如果你的函数返回多个值,并且你希望对行应用该函数,确保你的函数返回一个Series或类似的结构,这样Pandas才能正确地将其组装成一个新的DataFrame。

map()

在 pandas 中,map 函数是一种用于将一个函数或映射关系应用到 DataFrame 或 Series 的每个元素上的方法。对于 Series 对象,map 方法特别有用,因为它允许你将一个函数、字典或 Series 应用到 Series 的每个元素上,并返回一个新的 Series,其中包含应用映射后的结果。

以下是 map 方法的一些常见用法:

在 Series 中

import pandas as pd
 
# 创建一个 Series
s = pd.Series([1, 2, 3, 4, 5])
 
# 定义一个函数
def square(x):
    return x ** 2
 
# 使用 map 方法应用函数
squared_s = s.map(square)
print(squared_s)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这个例子中,square 函数被应用到 s Series 的每个元素上,结果是一个包含每个元素平方的新 Series。

字典进行映射

627. 变更性别

# 创建一个 Series
s = pd.Series(['cat', 'dog', 'fish', 'cat'])
 
# 定义一个映射字典
animal_to_sound = {'cat': 'meow', 'dog': 'woof', 'fish': 'glub'}
 
# 使用 map 方法应用字典映射
sounded_s = s.map(animal_to_sound)
print(sounded_s)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这个例子中,animal_to_sound 字典被用来将动物名称映射到它们的声音,结果是一个包含映射后声音的新 Series。

另一个 Series 进行映射

# 创建两个 Series
s1 = pd.Series(['a', 'b', 'c', 'd'])
s2 = pd.Series(['apple', 'banana', 'cherry', 'date'], index=['a', 'b', 'c', 'd'])
 
# 使用 map 方法应用 Series 映射
mapped_s = s1.map(s2)
print(mapped_s)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在这个例子中,s2 Series 被用作映射,将 s1 中的每个元素映射到 s2 中对应索引的值。注意,如果 s1 中的某个元素在 s2 的索引中找不到,结果将是 NaN。

对于 DataFrame,map 方法通常不是直接应用的,因为 DataFrame 是二维的,包含行和列。相反,你可能会对 DataFrame 的某一列使用 map 方法,或者对整个 DataFrame 使用 applymap 方法(但请注意,applymap 是应用于每个元素的,与 map 在 Series 上的行为类似,但它不接受函数以外的映射器)。

这里有一个对 DataFrame 列使用 map 的例子:

# 创建一个 DataFrame
df = pd.DataFrame({
    'Animal': ['cat', 'dog', 'fish', 'cat'],
    'Age': [2, 3, 1, 4]
})
 
# 使用 map 方法对 'Animal' 列应用字典映射
df['Sound'] = df['Animal'].map(animal_to_sound)
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这个例子中,animal_to_sound 字典被用来将 df DataFrame 中 'Animal' 列的每个元素映射到它们的声音,结果是一个新的列 'Sound'。

索引操作

idxmax()

总结:

DataFrame.idxmax():返回每列的最大值的行索引

Series.idxmax():返回单列的最大值的行索引

在 Pandas 中,idxmax() 函数用于返回指定轴上最大值的索引。这个函数对于寻找数据集中某个特定列(或行,取决于你如何应用它)的最大值的位置非常有用。

基本用法

假设你有一个 Pandas DataFrame 或 Series,idxmax() 会返回包含最大值的行(对于 DataFrame,默认是列方向)或元素(对于 Series)的索引。

import pandas as pd
 
# 创建一个简单的 DataFrame
df = pd.DataFrame({
    'A': [1, 20, 3, 4],
    'B': [5, 6, 70, 8]
})
 
# 对列 'A' 使用 idxmax()
max_index_A = df['A'].idxmax()
print(f"Column 'A' maximum value index: {max_index_A}")
 
# 对整个 DataFrame 使用 idxmax(),默认是 axis=0(列方向)
max_index_df = df.idxmax()
print(f"DataFrame maximum value indices (column-wise): {max_index_df}")
 
# 对 DataFrame 使用 idxmax(),指定 axis=1(行方向)
max_index_df_row = df.idxmax(axis=1)
print(f"DataFrame maximum value indices (row-wise): {max_index_df_row}")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

输出

Column 'A' maximum value index: 1
DataFrame maximum value indices (column-wise): A    1
B    2
dtype: int64
DataFrame maximum value indices (row-wise): 0    B
1    A
2    B
3    B
dtype: object
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

解释

  • 对于 df['A'].idxmax(),它返回列 ‘A’ 中最大值(20)的索引(1)。

  • 对于 df.idxmax()(默认 axis=0),它返回每一列中最大值的索引。在这个例子中,列 ‘A’ 的最大值在索引 1,列 ‘B’ 的最大值在索引 2。

  • 对于 df.idxmax(axis=1),它返回每一行中最大值的列索引。在这个例子中,第一行的最大值在列 ‘B’,第二行的最大值在列 ‘A’,依此类推。

注意事项

  • 如果存在多个最大值并且你想要找到它们所有的索引,idxmax() 只会返回第一个找到的最大值的索引。
  • 如果 DataFrame 或 Series 是空的,idxmax() 会抛出一个 ValueError。
  • 如果 DataFrame 中包含 NaN 值,并且你想要在忽略 NaN 的情况下找到最大值,你应该先使用 dropna() 方法去除 NaN 值,然后再应用 idxmax()。

reset_index()

在Pandas中,reset_index() 方法用于重置 DataFrame 或 Series 的索引。这个操作通常在你对数据进行了排序、分组、过滤等操作后,索引变得不再连续或不再是整数时特别有用。通过重置索引,可以使索引重新变为从 0 开始的整数序列,或者可以将某个列的值设置为新的索引。

以下是 reset_index() 方法的一些常用参数及其作用:

  • drop(布尔值,默认为 False):如果为 True,则不将旧索引添加为列;如果为 False,则旧索引会被添加为新的 DataFrame 的一列。
  • inplace(布尔值,默认为 False):如果为 True,则直接在原 DataFrame 上修改,不返回新的 DataFrame。
  • level(整数或索引级别名称,或级别列表):仅对多级索引有效。指定要重置的索引级别。
  • col_level(整数或索引级别名称):如果 DataFrame 的列是多级索引,则此参数指定用于新索引的列级别。
  • col_fill(字符串):用于填充多级列索引中缺失级别的值。

示例

参数name

596. 超过 5 名学生的课

例如,假设有一个DataFrame,其中’Name’列被设置为索引。如果想要重置这个索引,并且希望新的索引列有一个特定的名称(比如’ID’),就可以这样做:

df.set_index('Name', inplace=True)  # 将'Name'列设置为索引
reset_df = df.reset_index(name='ID')  # 重置索引,并指定新索引列的名称为'ID'
  • 1
  • 2

执行上述代码后,原来的’Name’索引就会被重置,并且会添加一个新的名为’ID’的列,其中包含了原来的索引值。

无参数

假设我们有一个 DataFrame:

import pandas as pd
 
df = pd.DataFrame({
    'A': ['foo', 'bar', 'baz', 'qux'],
    'B': [1, 2, 3, 4]
})
df = df.set_index('A')
print(df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

输出:

B
A     
foo  1
bar  2
baz  3
qux  4
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

现在我们将索引重置:

df_reset = df.reset_index()
print(df_reset)
  • 1
  • 2

输出:

A  B
0  foo  1
1  bar  2
2  baz  3
3  qux  4
  • 1
  • 2
  • 3
  • 4
  • 5

可以看到,原来的索引 ‘A’ 现在成为了一列,并且添加了一个新的从 0 开始的整数索引。

参数drop

如果我们不想保留原来的索引作为列,可以设置 drop=True:

df_reset = df.reset_index(drop=True)
print(df_reset)
  • 1
  • 2

输出:

B
0  1
1  2
2  3
3  4
  • 1
  • 2
  • 3
  • 4
  • 5

此时,原来的索引 ‘A’ 被丢弃,只保留了数据列 ‘B’ 和一个新的整数索引。

多级索引

对于多级索引,可以使用 level 参数来指定要重置的级别:

# 创建一个多级索引的 DataFrame
multi_index = pd.MultiIndex.from_tuples([('foo', 'one'), ('foo', 'two'), ('bar', 'one'), ('bar', 'two')], names=['A', 'B'])
df_multi = pd.DataFrame({'C': [1, 2, 3, 4]}, index=multi_index)
print(df_multi)
 
# 重置 'A' 级别的索引
df_reset_multi = df_multi.reset_index(level='A')
print(df_reset_multi)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

T

转置:列, 行交换

元素定位

at

626. 换座位

  • 用于访问单个值(标量访问),基于标签(label)进行索引。
  • 只能用于访问单个元素,如果访问多个元素会引发错误。
  • 适用于快速访问已知标签的数据。

df.at[row_label, column_label]
  • 1
  • 2

iat

  • 类似于at,但基于整数位置进行标量访问。
  • 适用于快速访问已知位置的单个元素。
df.iat[row_position, column_position]
  • 1

loc

  • 基于标签(label)进行索引,可以用于访问单个值或一组值。
  • 支持切片操作,可以访问行或列的子集。
  • 适用于基于标签的复杂查询。

df.loc[row_labels, column_labels]
  • 1
  • 2

iloc

  • 基于整数位置(integer position)进行索引,用于访问单个值或一组值。
  • 支持切片操作,可以访问行或列的子集。
  • 适用于基于位置的索引,当标签不是整数或不方便使用标签时很有用。

df.iloc[row_positions, column_positions]
  • 1
  • 2

两个序列操作

isin()

570. 至少有5名直接下属的经理

在 Pandas 中,isin() 方法用于过滤数据框(DataFrame)或序列(Series)中的元素,检查它们是否包含在指定的值列表或序列中。该方法返回一个布尔型对象(对于 DataFrame,返回一个布尔型的 DataFrame;对于 Series,返回一个布尔型的 Series),其中 True 表示元素包含在指定的值中,False 表示不包含。

以下是 isin() 方法的基本用法:

对于 Series

import pandas as pd
 
# 创建一个 Series
s = pd.Series([1, 2, 3, 4, 5])
 
# 使用 isin() 方法检查 Series 中的元素是否包含在 [1, 3, 5] 中
filtered_s = s[s.isin([1, 3, 5])]
 
print(filtered_s)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

输出将会是:

0    1
2    3
4    5
dtype: int64
  • 1
  • 2
  • 3
  • 4

对于 DataFrame

import pandas as pd
 
# 创建一个 DataFrame
df = pd.DataFrame({
    'A': [1, 2, 3, 4, 5],
    'B': [10, 20, 30, 40, 50]
})
 
# 使用 isin() 方法检查 DataFrame 的列 'A' 中的元素是否包含在 [1, 3, 5] 中
filtered_df = df[df['A'].isin([1, 3, 5])]
 
print(filtered_df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

输出将会是:

A   B
0  1  10
2  3  30
4  5  50
  • 1
  • 2
  • 3
  • 4

你也可以对 DataFrame 的多列使用 isin() 方法,但这时你需要分别对每个列进行过滤,或者结合使用其他逻辑操作(如 &、|)来组合多个过滤条件。

对多列使用 isin()(结合逻辑操作)

# 假设我们想要过滤出列 'A' 中的元素在 [1, 3] 中且列 'B' 中的元素在 [10, 30, 50] 中的行
combined_filter = (df['A'].isin([1, 3]) & df['B'].isin([10, 30, 50]))
filtered_df_multi = df[combined_filter]
 
print(filtered_df_multi)
  • 1
  • 2
  • 3
  • 4
  • 5

输出将会是:

A   B
0  1  10
2  3  30
4  5  50  # 注意:虽然 5 在 [1, 3] 中不在,但 50 在 [10, 30, 50] 中,所以这一行不会单独因为 B 列而被选中
# 但由于 5 不在 [1, 3] 中,所以实际上这一行不会被包括在结果中,这里只是为了解释逻辑操作。
# 正确的输出不会包含索引为 4 的行,因为它不满足 A 列的条件。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注意:上面的多列过滤示例中,我犯了一个错误并给出了一个误导性的输出解释。正确的行为是,只有当行同时满足所有列的条件时,它才会被包括在结果中。因此,在上面的例子中,索引为 4 的行不会被包括,因为 A 列的值 5 不在 [1, 3] 中。正确的输出应该只包含索引为 0 和 2 的行

注:本文转载自blog.csdn.net的yimoxi_no1的文章"https://blog.csdn.net/yimoxi_no1/article/details/145013921"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

131
学习和成长
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top