pandas 如何从df.itertuples中输入输出

tct7dpnv  于 2023-06-28  发布在  其他
关注(0)|答案(2)|浏览(125)

我有一个脚本如下

import pandas as pd

from typing import Any

def info(i: Any) -> None:
    print(f'{type(i)=:}')
    print(f'{i=:}')
    print(f'{i.Index=:}')
    print(f'{i.x=:}')
    print(f'{i.y=:}')

if __name__ == "__main__":
    df = pd.DataFrame([[1,'a'], [2, 'b']], columns=['x', 'y'])
    for i in df.itertuples():
        info(i)

其输出为

type(i)=<class 'pandas.core.frame.Pandas'>
i=Pandas(Index=0, x=1, y='a')
i.Index=0
i.x=1
i.y=a
type(i)=<class 'pandas.core.frame.Pandas'>
i=Pandas(Index=1, x=2, y='b')
i.Index=1
i.x=2
i.y=b

我想避免使用Any,但是在info函数中输入i的正确方法是什么?我的目标是让我知道i有字段Indexxy
如果我遵循pandas的输入方式(我仍然使用python3.8):

def info(i: Tuple[Any, ...]) -> None:

mypy抱怨道:

toy.py:8:11: error: "Tuple[Any, ...]" has no attribute "Index"; maybe "index"?  [attr-defined]
toy.py:9:11: error: "Tuple[Any, ...]" has no attribute "x"  [attr-defined]
toy.py:10:11: error: "Tuple[Any, ...]" has no attribute "y"  [attr-defined]
Found 3 errors in 1 file (checked 1 source file)
gab6jxml

gab6jxml1#

根据@Nick奥德尔的建议,使用NamedTuple似乎通过了我的检查:

import pandas as pd

from typing import NamedTuple

class Foo(NamedTuple):
    Index: int
    x: int
    y: str

def info(i: Foo) -> None:
    print(f'{type(i)=:}')
    print(f'{i=:}')
    print(f'{i.Index=:}')
    print(f'{i.x=:}')
    print(f'{i.y=:}')

if __name__ == "__main__":
    df = pd.DataFrame([[1,'a'], [2, 'b']], columns=['x', 'y'])
    for i in df.itertuples(name="Foo"):
        info(i)
e37o9pze

e37o9pze2#

要在info函数中正确输入变量i而不使用Any,可以使用pandas为itertuples方法提供的特定类型提示。itertuples返回的命名元组的类型提示是pandas.core.frame.Pandas。您可以直接在函数签名中导入和使用此类型。
下面是修改后的代码,其中包含了I的适当类型提示:

import pandas as pd
from typing import Tuple

def info(i: Tuple[int, int, str]) -> None:
    print(f'{type(i)=}')
    print(f'{i=}')

if __name__ == "__main__":
    df = pd.DataFrame([[1, 'a'], [2, 'b']], columns=['x', 'y'])
    for i in df.itertuples():
        info(I)

通过此修改,输出应为:

type(i)=<class 'pandas.core.frame.Pandas'>
i=Pandas(Index=0, x=1, y='a')
type(i)=<class 'pandas.core.frame.Pandas'>
i=Pandas(Index=1, x=2, y='b')

注意,类型提示Tuple[int,int,str]假设 Dataframe 具有两个整数列,后跟一个字符串列。如果实际的 Dataframe 具有不同的结构,请相应地调整类型提示。

相关问题