Pandas 截断 numpy 列表中的字符串

Pandas truncates strings in numpy list

提问人:GarethPrice 提问时间:3/22/2023 更新时间:3/22/2023 访问量:40

问:

请考虑以下最小示例:

@dataclass
class ExportEngine:

    def __post_init__(self):
        self.list = pandas.DataFrame(columns=list(MyObject.CSVHeaders()))

    def export(self):
        self.prepare()
        self.list.to_csv("~/Desktop/test.csv")

    def prepare(self):
        values = numpy.concatenate(
            (
                numpy.array(["Col1Value", "Col2Value", " Col3Value", "Col4Value"]),
                numpy.repeat("", 24),
            )
        )
        for x in range(8): #not the best way, but done due to other constraints
            start = 3 + (x * 3) - 2
            end = start + 3
            values[start:end] = [
                "123",
                "some_random_value_that_gets_truncated",
                "456",
            ]
        self.list.loc[len(self.list)] = values

调用时,被截断为:export()some_random_value_that_gets_truncatedsome_rando

['Col1Value', '123', 'some_rando', '456', '123', 'some_rando', '456', '123', 'some_rando', '456', '123', 'some_rando', '456', '123', ...] 

我尝试设置以下内容:

pandas.set_option("display.max_colwidth", 10000),但这并没有改变任何事情......

为什么会发生这种情况,如何防止截断?

python pandas list numpy 截断

评论

0赞 juanpa.arrivillaga 3/22/2023
你做了一个字符串的numpy数组,所以默认情况下,它将使用一个固定长度的字符串(这对numpy有意义)。如果你不想要,就不要使用 numpy 数组。dtype
0赞 juanpa.arrivillaga 3/22/2023
代码的重点在于创建 CSV 吗?为什么要使用 pandas 和 numpy?只需使用内置模块即可。或者无论如何,只是不要使用 .默认情况下,字符串使用 dtype,这将允许任意长度的字符串。只需使用 pandas,不涉及 numpy,或者在创建 numpy 数组时传递。但是使用似乎更简单,或者更好的是,只需在模块中使用常规 python,您就完全不必担心这样的事情csvnumpypandasobjectdtype=objectpandascsv
0赞 GarethPrice 3/22/2023
我需要它来创建 CSV、XLSX、JSON 等,这就是我选择熊猫的原因。但我可能不需要numpy......
0赞 juanpa.arrivillaga 3/22/2023
好的,我添加了一个答案,至少可以解决您的问题。

答:

1赞 juanpa.arrivillaga 3/22/2023 #1

因此,默认情况下会选择合适的固定长度 unicode 格式。numpy

请注意 dtype:

In [1]: import numpy

In [2]: values = numpy.concatenate(
   ...:     (
   ...:         numpy.array(["Col1Value", "Col2Value", " Col3Value", "Col4Value"]),
   ...:         numpy.repeat("", 24),
   ...:     )
   ...: )

In [3]: values
Out[3]:
array(['Col1Value', 'Col2Value', ' Col3Value', 'Col4Value', '', '', '',
       '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
       '', '', '', ''], dtype='<U10')

您可能不应该直接使用 numpy,但一个快速解决方法是替换:

values = numpy.concatenate(
    (
        numpy.array(["Col1Value", "Col2Value", " Col3Value", "Col4Value"]),
        numpy.repeat("", 24),
    )
)

跟:

values = np.array(
    ['Col1Value', 'Col2Value', ' Col3Value', 'Col4Value', *[""]*24], 
    dtype=object
)

请注意 ,它将仅使用指向 python 对象的指针,因此对字符串的长度没有限制dtype=objectstr

评论

0赞 GarethPrice 3/22/2023
这是有道理的,谢谢。我没有看到 numpy 使用固定长度的字符串(可能是出于效率原因)。你的回答有效,教会了我很多。谢谢。
0赞 juanpa.arrivillaga 3/22/2023
@GarethPrice是的,基本上,numpy是为在大型多维数组上进行快速数值计算而设计的。 本质上给你一个不太灵活/性能较低的 Python 列表,所以 API 通常假设你不想要它。dtype=object
1赞 constantstranger 3/22/2023 #2

这是代码的替代方法,它不依赖于 numpy(从而避免了 numpy 的固定宽度 unicode 字符串类型):

@dataclass
class ExportEngine:

    def __post_init__(self):
        # changed in this example to use numeric column labels equal in number:
        #self.list = pd.DataFrame(columns=list(MyObject.CSVHeaders()))
        self.list = pd.DataFrame(columns=range(4 + 24))

    def export(self):
        self.prepare()
        self.list.to_csv("~/Desktop/testXYZ.csv")

    def prepare(self):
        values = ["Col1Value", "Col2Value", " Col3Value", "Col4Value"] + [""] * 24
        values[1:1 + 24] = [
                "123",
                "some_random_value_that_gets_truncated",
                "456"
            ] * 8
        self.list.loc[0] = values