首页 > 其他分享 >将DataFrame 的每一列的列标题和每一行元素打包成一个元组 *zip

将DataFrame 的每一列的列标题和每一行元素打包成一个元组 *zip

时间:2023-11-21 10:32:58浏览次数:52  
标签:zip df zipped DataFrame 元组 arg row

将 DataFrame 的每一列的(列标题和每一行元素)打包成一个元组

将 DataFrame 的(列标题)和

    def fun_zip(
        self,
        df_arg=pd.DataFrame(),
        bool_arg=False
    ):
        # 每列元素打包
        zipped = zip(*[df_arg.iloc[i] for i in range(df_arg.shape[0])])
        # 是否包含标题
        if bool_arg:
            list_zip = [(col_name, *row) for col_name, row in zip(df_arg.columns, zipped)]
        else:
            list_zip = [tuple(row) for row in zipped]
        return list_zip

这段代码的目的是将一个 DataFrame 的每一列打包成一个元组,然后返回这些元组的列表。如果 bool_argTrue,则每个元组的第一个元素是列名。

这段代码已经很好地完成了这个任务,但是有一些地方可以进行优化:

  1. 默认参数:在函数定义中,尽量避免使用可变的默认参数,比如这里的 df_arg=pd.DataFrame()。这是因为默认参数在 Python 中只会被评估一次,如果你对默认参数进行了修改,那么这个修改会在下次调用函数时保留。所以,更好的做法是将默认参数设置为 None,然后在函数体中检查这个参数是否为 None,如果是,则赋予其默认值。
  2. 使用 itertools.zip_longest:在你的代码中,你使用了 zip 函数来打包每一列。然而,如果 DataFrame 的列长度不一致,zip 函数会忽略多出来的元素。为了避免这种情况,你可以使用 itertools.zip_longest 函数,它会用 None 来填充短的列。
  3. 使用 DataFrame.itertuples:Pandas 提供了一个 itertuples 方法,可以更高效地迭代 DataFrame 的行。你可以使用这个方法来替代 zip(*[df_arg.iloc[i] for i in range(df_arg.shape[0])])

考虑到以上的优化建议,你的代码可以改写成如下形式:

from itertools import zip_longest

def fun_zip(
    self,
    df_arg=None,
    bool_arg=False
):
    if df_arg is None:
        df_arg = pd.DataFrame()

    # 每列元素打包
    zipped = zip_longest(*df_arg.itertuples(index=False, name=None))
    # 是否包含标题
    if bool_arg:
        list_zip = [(col_name, *row) for col_name, row in zip(df_arg.columns, zipped)]
    else:
        list_zip = [row for row in zipped]
    return list_zip

在你提供的代码 zipped = zip_longest(*df_arg.itertuples(index=False, name=None)) 中,zip_longest 函数会返回一个迭代器,每个元素都是一个元组,元组中的元素对应于 df_arg 的每一行。

  • [tuple(row) for row in zipped]:这段代码会将 zipped 中的每个元素(已经是元组)转换为元组,所以这里的 tuple(row) 实际上没有改变 row 的数据类型。这意味着,最后得到的是一个元组的列表,列表中的每个元组对应于 df_arg 的一行。
  • [row for row in zipped]:这段代码会直接将 zipped 中的元素(元组)放入列表中,不进行任何类型转换。这意味着,最后得到的也是一个元组的列表,列表中的每个元组对应于 df_arg 的一行。

所以,在这个特定的情况下,[tuple(row) for row in zipped][row for row in zipped] 的结果是一样的,因为 zipped 中的元素已经是元组。


在 Python 中,self 是一个约定俗成的名字,用于指代实例本身。在类的方法中,我们通常将 self 作为第一个参数,以便可以在方法中引用实例的属性和其他方法。

然而,并不是所有的函数参数都需要前面加 self。只有当你需要在方法中访问或修改实例的属性时,才需要使用 self。如果一个变量只在方法内部使用,那么就不需要 self

例如,以下是一个类的定义,其中 self.name 是一个实例属性,而 greeting 只是 say_hello 方法的一个局部变量:

class Person:
    def __init__(self, name):
        self.name = name

    def say_hello(self):
        greeting = "Hello, " + self.name
        print(greeting)

在这个例子中,self.name 是需要 self 的,因为它是一个实例属性,我们希望在类的其他方法中也能访问到它。而 greeting 只在 say_hello 方法中使用,所以它不需要 self

总的来说,是否在变量前加 self,取决于你是否希望这个变量在整个实例中都可见。如果是,那么就需要 self;如果只是方法内部的临时变量,那么就不需要 self


你遇到的问题是由于 Python 的列表推导式(list comprehension)中不支持解包(unpacking)。在你的代码 [*row for row in zipped] 中,*row 是试图解包 row,但是在列表推导式中这是不被允许的。

如果你想要得到一个列表,其中每个元素都是 zipped 中的一个元组,你可以直接使用 list(zipped),或者使用列表推导式 [row for row in zipped]。这两种方式都可以得到相同的结果。

如果你想要将 zipped 中的所有元素解包成一个列表,你可以在列表推导式外部进行解包,像这样:[*zipped]。这样,你会得到一个列表,其中包含了 zipped 中所有元组的所有元素。



这段代码的目的是将 DataFrame 的每一列打包成一个元组,然后返回这些元组的列表。如果 bool_argTrue,则每个元组的第一个元素是列名。



检查并优化
    def fun_zip(
        self,
        df_arg=None,
        bool_arg=True
    ):
        if df_arg is None:
            df_arg = pd.DataFrame()

        # 每列元素打包
        zipped = zip_longest(*df_arg.itertuples(index=False, name=None))
        list_zip = list(zipped)
        # 是否包含标题
        if bool_arg:
            list_zip = [(col_name, *row) for col_name, row in zip(df_arg.columns, zipped)]
        return list_zip

这段代码已经很好地完成了这个任务,但是有一点需要注意:

在你的代码中,你先创建了 list_zip,然后在 if bool_arg: 的条件下可能会覆盖它。但是,如果 bool_argTruezip_longest(*df_arg.itertuples(index=False, name=None)) 这个迭代器在创建 list_zip 时已经被耗尽,所以在 zip(df_arg.columns, zipped) 中,zipped 是空的。这意味着,如果 bool_argTrue,你的函数会返回一个空列表。

为了解决这个问题,你可以在 if bool_arg: 的条件下重新创建 zipped,像这样:

from itertools import zip_longest
import pandas as pd

def fun_zip(
    self,
    df_arg=None,
    bool_arg=True
):
    if df_arg is None:
        df_arg = pd.DataFrame()

    # 每列元素打包
    zipped = zip_longest(*df_arg.itertuples(index=False, name=None))
    # 是否包含标题
    if bool_arg:
        list_zip = [(col_name, *row) for col_name, row in zip(df_arg.columns, list(zipped))]
    else:
        list_zip = list(zipped)
    return list_zip

这样,无论 bool_arg 的值是什么,你的函数都会返回正确的结果。希望这个建议对你有所帮助!


在 Python 中,迭代器是一个可以记住遍历的位置的对象。迭代器从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不像列表或者数组,迭代器不会一次性把所有元素加载到内存,而是需要时才生成元素。

迭代器(比如你在代码中使用的 zip_longest 函数返回的对象)是一次性的。这意味着迭代器中的元素在被访问后就会被丢弃,这就是所谓的 “迭代器被耗尽”。如果你试图再次从同一个迭代器中获取元素,你会发现它已经没有元素了,因为它们已经被访问并丢弃了。

例如,考虑以下代码:

my_list = [1, 2, 3]
my_iter = iter(my_list)

for item in my_iter:
    print(item)

for item in my_iter:
    print(item)

在这个例子中,第一个 for 循环会打印出列表中的所有元素。但是第二个 for 循环不会打印任何东西,因为迭代器已经被耗尽,所有的元素都已经被访问并丢弃了。

所以,如果你想要再次访问迭代器中的元素,你需要重新创建迭代器。希望这个解释能帮助你理解!


df.itertuples() 是 pandas DataFrame 的一个方法,它会返回一个迭代器,迭代器中的每个元素都是一个元组,元组中的元素对应于 DataFrame 的一行¹²。

这个方法有两个参数:

  • index:默认为 True。如果为 True,则返回的元组的第一个元素是索引¹。
  • name:默认为 'Pandas'。这个参数可以设置返回的 namedtuple 的名称。如果为 None,则返回普通的元组¹。

例如,假设我们有一个 DataFrame df

import pandas as pd

df = pd.DataFrame({
    'num_legs': [4, 2],
    'num_wings': [0, 2]
}, index=['dog', 'hawk'])

我们可以使用 itertuples() 来迭代 DataFrame 的行:

for row in df.itertuples():
    print(row)

输出:

Pandas(Index='dog', num_legs=4, num_wings=0)
Pandas(Index='hawk', num_legs=2, num_wings=2)

如果我们设置 index=False,则可以去掉索引:

for row in df.itertuples(index=False):
    print(row)

输出:

Pandas(num_legs=4, num_wings=0)
Pandas(num_legs=2, num_wings=2)

希望这个解释能帮助你理解!

(1) pandas.DataFrame.itertuples — pandas 2.1.3 documentation. https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.itertuples.html.

(2) Pandas DataFrame itertuples() Method - W3Schools. https://www.w3schools.com/python/pandas/ref_df_itertuples.asp.

(3) iterate over pandas dataframe using itertuples - Stack Overflow. https://stackoverflow.com/questions/43221208/iterate-over-pandas-dataframe-using-itertuples.

标签:zip,df,zipped,DataFrame,元组,arg,row
From: https://blog.51cto.com/u_16055028/8497509

相关文章

  • 【数据结构】数组和字符串(四):特殊矩阵的压缩存储:稀疏矩阵——三元组表
    4.2.1矩阵的数组表示【数据结构】数组和字符串(一):矩阵的数组表示4.2.2特殊矩阵的压缩存储  矩阵是以按行优先次序将所有矩阵元素存放在一个一维数组中。但是对于特殊矩阵,如对称矩阵、三角矩阵、对角矩阵和稀疏矩阵等,如果用这种方式存储,会出现大量存储空间存放重复信息或零......
  • [945] Replacing a string in all cells of a Pandas DataFrame
    ToreplaceastringinallcellsofaPandasDataFrame,wecanusethe str.replace()method,whichallowsustoperformstringreplacementsoneachelementofacolumn. Hereisanexample:importpandasaspd#CreateasampleDataFramedata={'Co......
  • java zip 压缩密码
    在Java开发中,Zip文件是一种常见的文件压缩格式。有时候我们需要给Zip文件添加密码保护,以确保文件的安全性。本文将指导你如何使用Java代码来实现Zip文件的添加密码功能。流程概述下面是实现“JavaZip添加密码”的整个流程:步骤描述步骤1创建一个Zip文件步骤2向Zi......
  • minizip 压缩
    所以想用minizip还有点复杂呢。另外,无论是zlib还是minizip都是C语言写出来的,代码看起来工整简洁。C++minizip的简单使用,zip文件的创建、读取、修改、密码压缩、4G以上大文件压缩。-CSDN博客......
  • vue2 项目打包后自动压缩成zip文件
    安装依赖1pnpminstallfilemanager-webpack-plugin--save-dev在vue.config.js中添加如下代码constFileManagerPlugin=require('filemanager-webpack-plugin')//引入插件1configureWebpack:{2plugins:[3newFileManagerPlugin({......
  • 元组
    元组是Pythont中内置的不可变序列元组在Python中使用O定义元组,元素与元素之间使用英文的逗号分隔元组中只有一个元素的时候,逗号也不能省略元组的创建方式1.使用()直接创建元组示例:元组名=(10,20,30,40)2.使用内置函数tuple()创建元组语法结构:元组名=tuple(序列)删除元组:del元组......
  • 关于Dataframe数据保存出现的问题
    问题描述:读入csv文件,执行以下程序importpandasaspdimportnumpyasnp#pd.set_option('max_colwidth',2000)sub_file_name="submission.csv"df=pd.read_csv(sub_file_name,header=None)pro_file_name="problem.csv"df2=pd.read_csv(pro_fi......
  • 常见面试题-Redis底层的SDS、ZipList、ListPack
    Redis的SDS了解吗?答:Redis创建了SDS(simpledynamicstring)的抽象类型作为String的默认实现SDS的结构如下:structsdshdr{//字节数组,用于保存字符串charbuf[];//buf[]中已使用字节数量,称为SDS的长度intlen;//buf[]中尚未使用的字节数量intfree;}......
  • Linux命令gzip、bzip、tar、zip区别:
     转载: 【彷徨|Linux各个压缩命令(gzip,bzip2,zip,tar)的特点及区别详解】https://mbd.baidu.com/ma/s/3Wi3H7BE1:gzipgzip只能压缩(解压)文件,不能压缩目录,后缀名为.gz, 而且不保留原文件 解压使用gzip–d或者gunzip[root@localhosttest_tar]##压缩[root@......
  • 压缩包Zip格式详析(全网最详细)
    原文:https://blog.csdn.net/qq_43278826/article/details/118436116【前言】     Android的安装包.apk实际上就是个zip格式的压缩包,所以在了解apk签名之前,有必要先来探索一下zip格式压缩包的结构一、Zip格式结构图总览  二、Zip文件结构详解zip格式压缩包主要由......