为什么 pandas 的 Dataframe.to_csv 和 Series.to_csv 输出不同?

3
我需要一个以逗号分隔的单行CSV文件。我的问题是,当我尝试使用apply迭代我的数据框时,我得到了一个Series对象,而to_csv方法给出一个str分成多行,并将None设置为"",没有任何逗号。但如果我使用for迭代数据框,我的方法会得到一个Dataframe对象,它会在一行中给出一个带有逗号的str,而不将None设置为""。以下是用于测试的代码:
import pandas


def print_csv(tabular_data):
    print(type(tabular_data))
    csv_data = tabular_data.to_csv(header=False, index=False)
    print(csv_data)


df = pandas.DataFrame([
    {"a": None, "b": 0.32, "c": 0.43},
    {"a": None, "b": 0.23, "c": 0.12},
])

df.apply(lambda x: print_csv(x), axis=1)

for i in range(0, df.shape[0]):
    print_csv(df[i:i+1])

使用apply输出控制台:

<class 'pandas.core.series.Series'>
""
0.32
0.43
<class 'pandas.core.series.Series'>
""
0.23
0.12

for 循环的控制台输出:

<class 'pandas.core.frame.DataFrame'>
,0.32,0.43
<class 'pandas.core.frame.DataFrame'>
,0.23,0.12

我在我的函数中尝试使用csv_data = tabular_data.to_csv(header=False, index=False, sep=','),但是我得到了相同的输出。

为什么我在DataFrameSeries中使用to_csv方法时得到不同的输出?

需要进行哪些更改以使apply产生与for相同的结果?


DataFrame.apply方法传递一个Series,无论axis=0是列Series,还是axis=1将行转换为Series。据我所知,您无法更改这一点。 - ALollz
1
为什么需要使用 apply,不能直接执行 df.to_csv(header=False, index=False) - BioGeek
@ALollz 是的,我知道这一点,但我不知道为什么两个 to_csv 方法会给出不同的结果。 - Franco Morero
1
@FrancoMorero 随后迭代csv文件的每一行:for line in df.to_csv(header=False, index=False).splitlines(): ... - BioGeek
@Thymen 我使用的是 pandas 1.2.4 版本,并且在使用 result_type='broadcast' 参数时,得到的输出与我在问题中发布的一样。我的代码是:df.apply(lambda x: print_csv(x), axis=1, result_type='broadcast'),请问我做错了什么? - Franco Morero
显示剩余6条评论
1个回答

1

嗯,我做了很多研究,我的输出结果与众不同,因为这是预期的行为。我在Pandas存储库中找到了一个PR,其中一些贡献者添加了一个带有Series.to_csv片段的评论,并且具有与我相同的输出结果(这是来自toobaz的评论)。

因为Series是DataFrame的单列数据结构,所以我的print_csv函数实际上得到的是一个包含我的数据的单列数据结构(当使用df.apply(lambda x: print_csv(x), axis=1)为一个对象调用时,print_csv内部的print(tabular_data.head())的输出结果):

<class 'pandas.core.series.Series'>
a    None
b    0.23
c    0.12
Name: 1, dtype: object

因为它会为每列生成一行,所以CSV可以这样。

""
0.23
0.12

我需要做的是将一列数据结构转换为一行数据结构。为此,我使用pandas.Series.to_frame将Series对象转换为DataFrame,并对其进行转置(我使用DataFrame的属性T,它是pandas.DataFrame.transpose的访问器)。
我将apply函数更改为:
df.apply(lambda x: print_csv(x.to_frame().T), axis=1)

并且在使用问题中的DataFrame(使用示例数据)调用apply中的print_csv新输出与我的预期相同:

<class 'pandas.core.frame.DataFrame'>
,0.32,0.43
<class 'pandas.core.frame.DataFrame'>
,0.23,0.12

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接