如何使pandas read_csv处理numpy str(或unicode)标量数据类型

时间:2015-02-19 18:28:08

标签: python-3.x numpy pandas

每当我读取包含一列字符串的CSV文件时,我发现默认情况下pandas会将dtype作为objectmydf['mycol'].astype(str)。我已尝试使用dtypemycolobjectstr更改为dtype,但它无法正常工作 - 它没有给我一个错误,但与此同时,pandas保持不变。

我读到numpy已构建在numpy之上,str_同时允许unicode_pandas see here: numpy scalar types。我不熟悉numpy的内部工作原理,一般不熟悉pandas.io.parsers.read_csv

  1. 使用dtype确保CSV文件中的一列字符串被str object而不是pandas.io.parsers.read_csv(filepath_or_buffer, sep=', ', dialect=None, compression=None, doublequote=True, escapechar=None, quotechar='"', quoting=0, skipinitialspace=False, lineterminator=None, header='infer', index_col=None, names=None, prefix=None, skiprows=None, skipfooter=None, skip_footer=0, na_values=None, na_fvalues=None, true_values=None, false_values=None, delimiter=None, converters=None, dtype=None, usecols=None, engine=None, delim_whitespace=False, as_recarray=False, na_filter=True, compact_ints=False, use_unsigned=False, low_memory=True, buffer_lines=None, warn_bad_lines=True, error_bad_lines=True, keep_default_na=True, thousands=None, comment=None, decimal='.', parse_dates=False, keep_date_col=False, dayfirst=False, date_parser=None, memory_map=False, float_precision=None, nrows=None, iterator=False, chunksize=None, verbose=False, encoding=None, squeeze=False, mangle_dupe_cols=True, tupleize_cols=False, infer_datetime_format=False, skip_blank_lines=True) 读取时,我能做些什么? ?
  2. 更具体地说,我需要使用哪些参数(来自下面给出的参数)来实现这一目标?

    pandas.io.parsers.read_csv
    1. 有点相关:在''的参数中是否有任何变量/标志可以自动从字符串列中读取缺少的字符串nan(空字符串)而不是读取缺少的字符串pandas.io.parsers.read_csv
    2. 此外,文档中未描述可传递给na_fvalues的许多参数:pandas.io.parsers.read_csv.html,例如use_unsignedcompact_ints,{{1}除了阅读代码(有点长)之外,是否还有任何可以获得所有参数的更详细文档的地方?

1 个答案:

答案 0 :(得分:2)

这是Wes 采用numpy的字符串数据类型的技术决策:Numpy将所有字符串分配为相同的大小。

在大多数现实世界的用例中,字符串不是固定大小的,通常有一些很长。分配一个非常大的连续内存块(和IIRC,这是浪费的), 违反直觉,可以更慢!)将它们存储为固定大小:

In [11]: np.array(["ab", "a"])  # The 2 is the length
Out[11]:
array(['ab', 'a'],
      dtype='|S2')

In [12]: np.array(['this is a very long string', 'a', 'b', 'c'])
Out[12]:
array(['this is a very long string', 'a', 'b', 'c'],
      dtype='|S26')

举一个愚蠢的例子,我们可以看到一个例子,其中对象dtype占用的内存较少:

In [21]: a = np.array(['a'] * 99 + ['this is a very long string, really really really really really long, oh yes'])

In [22]: a.nbytes
Out[22]: 7500

In [23]: b = a.astype(object)

In [24]: b.nbytes + sum(sys.getsizeof(item) for item in b)
Out[24]: 4674

还有一些"令人惊讶的" numpy字符串的行为(也是由于它们的布局):

In [31]: a = np.array(['ab', 'c'])

In [32]: a[1] = 'def'

In [33]: a  # what the f?
Out[33]:
array(['ab', 'de'],
      dtype='|S2')

如果你想修复这种行为 - 并保持numpy字符串dtype - 你必须为每个作业制作一个副本。 (使用对象数组,您可以免费获得:只需更改指针。)


因此,在pandas中,使用对象dtype存储字符串。

注意:我认为有一部分文档讨论了这个决定,但我似乎无法找到它......