目录:

一、在Dataframe的最后插入一列

二、指定Dataframe一列的数据类型

三、遍历Dataframe的每一行,为什么修改行里的数据不会同步修改到Dataframe中

四、Dataframe删除重复的行 

五、Dataframe删除列

六、Dataframe重排索引

七、给Dataframe增加一列,每次遍历给该新增列中的元素赋值

八、将字典嵌套列表转换为Dataframe

九、Dataframe中at、loc、iloc的区别

一、在dataframe的最后插入一列

如果想在 DataFrame 的最后插入一列,可以通过以下几种方法来实现。

方法 1:直接赋值新列

可以通过直接为 DataFrame 赋值新列,添加一个新列来将其插入到最后。

import pandas as pd

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

# 新列数据
new_column = [7, 8, 9]

# 在 DataFrame 的最后插入新列
df['C'] = new_column

# 打印结果
print(df)

 输出:

   A  B  C
0  1  4  7
1  2  5  8
2  3  6  9

在这个例子中,通过直接赋值为列 'C' 插入了新列。

如果需要将新的列数据设置为某个常数值,可以直接赋值为常数。

示例(常数值):

df['D'] = 10  # 将新列 D 的所有值都设置为 10

如果要向DataFrame的最后添加一列,通常你只需要保证新列的长度与现有DataFrame的行数相匹配。 

方法 2:使用 insert 方法

虽然 insert 方法通常用于在指定位置插入列,但你也可以将其用来在最后插入列。为了插入到最后,只需要指定位置为 len(df.columns)

# 使用 insert 在最后插入新列
df.insert(len(df.columns), 'C', new_column)

# 打印结果
print(df)

输出:

   A  B  C
0  1  4  7
1  2  5  8
2  3  6  9

解释:

  • df.insert(len(df.columns), 'C', new_column) 中,len(df.columns) 表示列的总数,表示我们要把新列插入到最后一个位置。
  • 'C' 是新列的列名,new_column 是列的数据。
  • 方法 3:使用 assign 方法

    你还可以使用 assign 方法来添加新列。该方法会返回一个新的 DataFrame,因此你需要将结果重新赋值给原 DataFrame

    # 使用 assign 添加新列
    df = df.assign(C=new_column)
    
    # 打印结果
    print(df)
    

    输出: 

       A  B  C
    0  1  4  7
    1  2  5  8
    2  3  6  9
    

    assign 方法会返回一个新的 DataFrame,所以它的行为类似于直接赋值,只不过它更适合链式操作。

    二、指定Dataframe一列的数据类型 

     使用astype() 手动指定列的数据类型

    df['A'] = df['A'].astype(str)
    df['B'] = df['B'].astype(int)
    df['C'] = df['C'].astype(object)

    三、遍历Dataframe的每一行,为什么修改行里的数据不会同步修改到Dataframe中 

    在 Pandas 中,遍历 DataFrame 的每一行时,如果直接修改行中的数据,修改的内容不会自动同步到原始 DataFrame。这是因为当你遍历行时,实际上你得到的是该行的一个副本,而不是对 DataFrame 本身的引用。修改副本不会影响原始的 DataFrame。

    为了更清晰地理解,来看以下两个方面的详细解释:

    1. 通过 .iterrows() 遍历行

    import pandas as pd
    
    data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
    df = pd.DataFrame(data)
    
    for index, row in df.iterrows():
        row['A'] = row['A'] + 1  # 修改行副本中的值
    
    print(df)
    

    输出:

       A  B
    0  1  4
    1  2  5
    2  3  6
    

    这里,df.iterrows() 返回的是每一行的 副本,你修改的是副本中的 row 对象,而不是原始 DataFrame 中的值。因此,修改后的值不会同步回 df。 

    2. 为什么修改不会反映到 DataFrame?

    .iterrows() 中,每一行返回的是一个 Series 对象,它是原 DataFrame 中这一行数据的副本(而不是引用)。这意味着对 row 的修改不会影响到原始的 DataFrame。Python 中的赋值操作(如 row['A'] = row['A'] + 1)会修改副本的内容,但不会修改原 DataFrame。

    3. 解决方法:通过 .iloc[] 或 .loc[] 修改原 DataFrame

    为了确保对 DataFrame 中的行修改是有效的,我们应该直接修改原 DataFrame 中的元素,而不是修改副本。可以通过 .iloc[].loc[] 进行修改。 

    示例 1: 使用 .iloc[]
    import pandas as pd
    
    data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
    df = pd.DataFrame(data)
    
    for index, row in df.iterrows():
        df.loc[index, 'A'] = row['A'] + 1  # 直接修改原 DataFrame
    
    print(df)
    

    输出:

       A  B
    0  2  4
    1  3  5
    2  4  6
    

    在这个例子中,我们使用 df.loc[index, 'A'] 来直接修改原 DataFrame 中 A 列的值。

    示例 2: 使用 .loc[]

    import pandas as pd
    
    data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
    df = pd.DataFrame(data)
    
    for index, row in df.iterrows():
        df.loc[index, 'A'] = row['A'] + 1  # 直接修改原 DataFrame
    
    print(df)
    

    总结: 

  • .iterrows() 返回的是 DataFrame 行的副本,对副本的修改不会影响原 DataFrame。
  • 要确保修改生效,应使用 .loc[] 或 .iloc[] 来直接修改 DataFrame 中的元素。
  • 四、Dataframe删除重复的行

    pandas 中删除 DataFrame 中的重复行,可以使用 drop_duplicates() 方法。以下是一些常见的用法示例:

    1. 删除所有重复的行(基于所有列) 

    import pandas as pd
    
    # 创建一个示例DataFrame
    data = {'A': [1, 2, 2, 3, 3], 'B': [4, 5, 5, 6, 6]}
    df = pd.DataFrame(data)
    
    # 删除所有重复的行
    df = df.drop_duplicates()
    
    print(df)
    

     2. 删除基于特定列的重复行

    你可以指定要检查重复的列。如果只想基于某些列来删除重复的行,可以使用 subset 参数

    # 删除基于列 'A' 的重复行
    df = df.drop_duplicates(subset=['A'])
    
    print(df)
    

    3. 保留第一次出现的行或最后一次出现的行

    # 保留最后一次出现的重复行
    df = df.drop_duplicates(keep='last')
    
    print(df)
    
  • keep='first':默认值,保留第一次出现的行。
  • keep='last':保留最后一次出现的行。
  • keep=False:删除所有重复的行。
  • 4. 使用 inplace=True 直接修改原始 DataFrame 

    如果不想创建一个新的 DataFrame,可以使用 inplace=True 参数直接修改原始的 DataFrame。 

    df.drop_duplicates(inplace=True)
    

    总结:

  • drop_duplicates() 是删除重复行的主要方法。
  • 可以通过 subset 参数指定某些列,keep 参数控制保留哪些重复行。
  • 五、Dataframe删除列 

     在 pandas 中删除 DataFrame 的列,可以使用 drop() 方法。以下是如何删除列的几种常见方法:

    1. 删除单列或多列

    import pandas as pd
    
    # 创建一个示例DataFrame
    data = {'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]}
    df = pd.DataFrame(data)
    
    # 删除单列 'B'
    df = df.drop('B', axis=1)
    
    # 删除多列 'A' 和 'C'
    df = df.drop(['A', 'C'], axis=1)
    
    print(df)
    

    2. 使用 inplace=True 参数

    如果不想创建新的 DataFrame,可以直接在原始 DataFrame 上删除列,使用 inplace=True 参数。 

    df.drop('B', axis=1, inplace=True)
    

    3. 使用 del 关键字

    如果你确定列名存在,可以使用 del 关键字来删除列。

    del df['B']
    

    4. 参数说明:

  • axis=1 表示按列删除。如果要按行删除,使用 axis=0
  • inplace=True 会直接修改原始 DataFrame,而不是返回一个新的 DataFrame
  • 六、Dataframe重拍索引

     在 Pandas 中,你可以使用 reset_index()set_index() 方法来重新排列 DataFrame 的索引。具体来说:

    1. 重设索引(reset_index)

    如果你想将当前的索引重置为默认的整数索引,并把原来的索引列转化为普通列,可以使用 reset_index()

    import pandas as pd
    
    # 创建一个简单的 DataFrame
    data = {'A': [1, 2, 3], 'B': [4, 5, 6]}
    df = pd.DataFrame(data, index=['a', 'b', 'c'])
    
    # 重设索引
    df_reset = df.reset_index()
    
    print(df_reset)
    

    输出:

      index  A  B
    0     a  1  4
    1     b  2  5
    2     c  3  6
    

     默认情况下,reset_index() 会把旧的索引列添加为普通列,并为 DataFrame 创建新的默认整数索引。如果你不想把旧的索引列保留在 DataFrame 中,可以使用 drop=True 参数

    df_reset = df.reset_index(drop=True)
    

    2. 设置新索引(set_index)

    如果你想根据 DataFrame 中的一列或几列数据设置新的索引,可以使用 set_index()

    # 设置 'A' 列作为新的索引
    df_set = df.set_index('A')
    
    print(df_set)
    

     输出:

       B
    A   
    1  4
    2  5
    3  6
    

     3. 重排序索引

    如果你想对现有索引进行排序,可以使用 sort_index() 方法。例如: 

    # 按照索引排序
    df_sorted = df.sort_index(ascending=False)
    
    print(df_sorted)
    

     输出:

       A  B
    c  3  6
    b  2  5
    a  1  4
    

     4. 多层索引(MultiIndex)中的重排

    如果你的 DataFrame 使用了多层索引(MultiIndex),你也可以通过 reset_index()set_index() 来调整层级。

    示例:设置多层索引 

    # 创建 MultiIndex DataFrame
    arrays = [['a', 'a', 'b', 'b'], ['x', 'y', 'x', 'y']]
    index = pd.MultiIndex.from_arrays(arrays, names=('letter', 'number'))
    
    df_multi = pd.DataFrame({'value': [10, 20, 30, 40]}, index=index)
    
    print(df_multi)
    

    输出:

                   value
    letter number       
    a      x          10
           y          20
    b      x          30
           y          40
    

    示例:重设 MultiIndex

    # 重设索引
    df_reset_multi = df_multi.reset_index()
    
    print(df_reset_multi)
    

     输出:

      letter number  value
    0      a      x     10
    1      a      y     20
    2      b      x     30
    3      b      y     40
    

    七、给Dataframe增加一列,每次遍历给该新增列中的元素赋值 

    pandas 中给 DataFrame 增加一列,并且通过遍历给该列中的元素赋值,可以通过多种方式实现。你可以使用 iterrows()apply() 等方法来遍历 DataFrame 的每一行,并对新增列进行赋值。

    方法 1:使用 iterrows() 遍历

    iterrows() 是一个迭代器,它可以逐行遍历 DataFrame,返回每行的索引和数据。你可以在遍历过程中为新增列赋值。

    import pandas as pd
    
    # 示例 DataFrame
    data = {
        'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35]
    }
    df = pd.DataFrame(data)
    
    # 增加一列 'NewColumn',初始为空
    df['NewColumn'] = None
    
    # 使用 iterrows() 遍历 DataFrame 并给 'NewColumn' 列赋值
    for index, row in df.iterrows():
        # 给新增列赋值
        df.at[index, 'NewColumn'] = f"Value_{index}"
        # df.loc[index, 'NewColumn'] = f"Value_{index}"
    
    # 打印结果
    print(df)
    

    输出:

          Name  Age  NewColumn
    0    Alice   25  Value_0
    1      Bob   30  Value_1
    2  Charlie   35  Value_2
    

    方法 2:使用 apply() 方法

    apply() 方法通常比 iterrows() 更高效。如果你对每一行或每一列进行操作,可以使用 apply()方法 结合 lambda 函数来进行赋值。 

    示例:

    import pandas as pd
    
    # 示例 DataFrame
    data = {
        'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35]
    }
    df = pd.DataFrame(data)
    
    # 使用 apply() 给 'NewColumn' 列赋值
    df['NewColumn'] = df.apply(lambda row: f"Value_{row.name}", axis=1)
    
    # 打印结果
    print(df)
    

    输出:

          Name  Age  NewColumn
    0    Alice   25  Value_0
    1      Bob   30  Value_1
    2  Charlie   35  Value_2
    

    说明:

  • iterrows() 可以逐行遍历 DataFrame,但效率较低,尤其对于较大的数据集。
  • apply() 是对每一行或每一列应用一个函数,通常会比 iterrows() 更高效。row.name 会返回当前行的索引,可以用来动态地为每一行生成值。
  • 方法 3:通过 for 循环直接赋值(适用于小型 DataFrame) 

    可以通过 for 循环直接遍历 DataFrame 的索引,并赋值。

    示例:

    import pandas as pd
    
    # 示例 DataFrame
    data = {
        'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35]
    }
    df = pd.DataFrame(data)
    
    # 增加一列 'NewColumn',初始为空
    df['NewColumn'] = None
    
    # 使用 for 循环给 'NewColumn' 列赋值
    for i in range(len(df)):
        df.loc[i, 'NewColumn'] = f"Value_{i}"
    
    # 打印结果
    print(df)
    

    输出:

          Name  Age  NewColumn
    0    Alice   25  Value_0
    1      Bob   30  Value_1
    2  Charlie   35  Value_2
    

    总结:

  • 使用 iterrows() 可以遍历每一行并逐一赋值。
  • 使用 apply() 更为简洁且高效,尤其适合对每一行做操作。
  • 对于较小的 DataFrame,直接用 for 循环和 loc 也可以完成任务。
  • 选择合适的方法取决于你数据的规模和操作的复杂性。

    八、将字典嵌套列表转换为Dataframe

    如果你有一个字典嵌套列表,并且想将其转换为 pandas 的 DataFrame,通常的做法是将字典的每个键视作 DataFrame 的列,字典的值(如果是列表或其他可迭代对象)作为对应列的元素。 

    下面是一些常见的示例,展示如何将字典嵌套列表转换为 DataFrame

    示例 1:字典嵌套列表(每个键对应一个列表)

    有如下字典:

    import pandas as pd
    
    # 字典嵌套列表
    data = {
        'A': [1, 2, 3],
        'B': [4, 5, 6],
        'C': [7, 8, 9]
    }
    

    可以直接将其转换为 DataFrame:

    df = pd.DataFrame(data)
    print(df)
    

    输出: 

       A  B  C
    0  1  4  7
    1  2  5  8
    2  3  6  9
    

     示例 2:字典嵌套列表(每个键对应一个字典)

    如果你有一个字典嵌套字典的情况,每个值是一个字典(通常字典中的键是列名,值是列的值),可以通过将这个字典转换为 DataFrame 来实现:

    data = {
        'row1': {'A': 1, 'B': 4, 'C': 7},
        'row2': {'A': 2, 'B': 5, 'C': 8},
        'row3': {'A': 3, 'B': 6, 'C': 9}
    }
    
    df = pd.DataFrame.from_dict(data, orient='index')
    print(df)
    

    输出:

          A  B  C
    row1  1  4  7
    row2  2  5  8
    row3  3  6  9
    

    在这个例子中,我们使用了 pd.DataFrame.from_dict() 函数,并且指定了 orient='index',这意味着字典的键(例如 'row1', 'row2')将成为 DataFrame 的行索引。

    示例 3:字典嵌套列表(每个字典中有不同长度的列表)

    如果你的字典嵌套的是不规则的列表(即字典的每个键对应不同长度的列表),pandas 会自动处理缺失值(用 NaN 填充缺失的数据)。

    data = {
        'A': [1, 2, 3],
        'B': [4, 5],
        'C': [7, 8, 9]
    }
    
    df = pd.DataFrame.from_dict(data, orient='index').transpose()
    print(df)
    

    输出:

         A    B  C
    0  1.0  4.0  7
    1  2.0  5.0  8
    2  3.0  NaN  9
    

    在这个例子中,列 'B' 少了一个元素,因此缺失的地方会被自动填充为 NaN

    示例 4:字典嵌套列表,包含嵌套结构

    如果字典值本身包含嵌套结构(如列表中的字典),你可以通过一些额外的处理将嵌套数据展平,然后转换为 DataFrame。

    假设你的数据如下:

    data = {
        'ID': [1, 2],
        'Details': [
            {'name': 'Alice', 'age': 25},
            {'name': 'Bob', 'age': 30}
        ]
    }
    

     如果你希望将嵌套的字典展开并放入 DataFrame 中,可以先处理嵌套字典:

    # 将 'Details' 列展开
    df = pd.json_normalize(data, 'Details', ['ID'])
    print(df)
    

     输出:

        name  age  ID
    0  Alice   25   1
    1    Bob   30   2
    

    这里使用了 pd.json_normalize() 来展开 Details 列中的嵌套字典。

    总结

  • 对于字典嵌套列表的转换,通常可以直接使用 pd.DataFrame() 或 pd.DataFrame.from_dict()
  • 如果字典嵌套了更复杂的结构(如嵌套字典),可以使用 pd.json_normalize() 来展开字典。
  • 如果列表的长度不一致,pandas 会自动使用 NaN 填充缺失的数据。
  • 根据你的数据结构的复杂程度,你可以选择不同的方式来处理和转换为 DataFrame。

    九、Dataframe中at、loc、iloc的区别

    在Pandas中,atlociloc 是用于访问和操作 DataFrame 中数据的方法,它们有不同的应用场景和行为。以下是它们的主要区别:

    1. at

  • 用途at 是用于访问单个元素,通常用于基于行标签和列标签的快速访问。
  • 功能:只允许通过单个行标签和列标签来访问单个数据点。
  • 速度:相较于 loc 和 ilocat 在访问单个元素时会更快,因为它专门优化了这个操作。
  • 用法df.at[row_label, column_label]
  • 示例: 

    import pandas as pd
    df = pd.DataFrame({
        'A': [1, 2, 3],
        'B': [4, 5, 6]
    })
    value = df.at[1, 'B']  # 访问第2行、第B列的值,结果是5
    

    2. loc

  • 用途loc 是基于标签(即行和列的名称)进行访问的。它可以用于选择行、列或行列的子集,支持切片。
  • 功能:支持根据行和列标签来选择数据,可以传递标签列表或进行切片操作。
  • 用法df.loc[row_labels, column_labels],其中 row_labels 和 column_labels 可以是标签列表、单个标签或者切片。
  • 注意loc 允许选择多个行和列,可以传递标签范围进行切片。
  • 示例:

    value = df.loc[1, 'B']  # 访问第2行、第B列的值,结果是5
    subset = df.loc[0:2, ['A']]  # 获取第0到第2行和列'A'的子集
    

    3. iloc

  • 用途iloc 是基于整数位置(即行和列的索引位置)进行访问的。它类似于 Python 中的列表索引,用整数来选择行和列。
  • 功能:支持通过整数位置来访问 DataFrame 的元素,可以进行切片操作,和 loc 相似,但是使用位置索引而非标签索引。
  • 用法df.iloc[row_positions, column_positions],其中 row_positions 和 column_positions 是行列的整数位置,可以是单个位置、列表、或切片。
  • 注意iloc 不支持标签索引。
  • 示例:

    value = df.iloc[1, 1]  # 访问第2行、第2列的值,结果是5
    subset = df.iloc[0:2, [0]]  # 获取第0到第1行和第0列的子集
    

    总结:

    方法 基于 用法例子 描述
    at 标签 df.at[1, 'B'] 访问单个元素,基于行标签和列标签,速度较快
    loc 标签 df.loc[1, 'B'] 基于行列标签选择数据,可以切片、选择多个行列的子集
    iloc 整数位置 df.iloc[1, 1] 基于整数位置选择数据,支持切片和位置索引选择多个行列

    选择时的考虑:

  • 如果你只需要访问单个元素,使用 at 会更高效。
  • 如果你需要基于标签来选取行或列,使用 loc
  • 如果你需要基于整数位置来访问数据,使用 iloc
  •  

    作者:whale fall

    物联沃分享整理
    物联沃-IOTWORD物联网 » python Dataframe操作

    发表回复