Pandas read_csv dtype读取所有列,但少数列为字符串

baubqpgj  于 2023-02-10  发布在  其他
关注(0)|答案(4)|浏览(160)

我正在使用Pandas来读取一堆CSV,通过向dtype参数传递一个options json来告诉Pandas哪些列要读取为字符串,而不是默认值:

dtype_dic= { 'service_id':str, 'end_date':str, ... }
feedArray = pd.read_csv(feedfile , dtype = dtype_dic)

在我的场景中,***所有***列(除了少数几个特定列)都将被读取为字符串。因此,我不想在dtype_dic中将几个列定义为str,而是只将我选择的几个列设置为int或float。有没有办法做到这一点?
这是一个循环,循环遍历具有不同列的各个CSV,因此在将整个csv读取为string(dtype=str)后直接进行列转换并不容易,因为我无法立即知道csv包含哪些列。(我宁愿花精力定义dtype json中的所有列!)
编辑:但是,如果有一种方法可以处理要转换为数字的列名列表,而不会在该列不存在于该csv中时出错,那么是的,这将是一个有效的解决方案,如果没有其他方法可以在csv阅读阶段完成此操作的话。
注意:这听起来像like a previously asked question,但是那里的答案走了一个非常不同的路径(布尔相关),这不适用于这个问题。请不要标记为重复!

erhoui1w

erhoui1w1#

对于Pandas 1.5.0+,有一个简单的方法可以做到这一点。如果你使用defaultdict而不是dict作为dtype参数,任何没有明确列在字典中的列将使用默认类型。

from collections import defaultdict
types = defaultdict(str, A="int", B="float")
df = pd.read_csv("/path/to/file.csv", dtype=types, keep_default_na=False)

(我还没有对此进行测试,但我认为您仍然需要keep_default_na=False
对于旧版本的Pandas:
您可以将整个csv读取为字符串,然后将所需的列转换为其他类型,如下所示:

df = pd.read_csv('/path/to/file.csv', dtype=str, keep_default_na=False)
# example df; yours will be from pd.read_csv() above
df = pd.DataFrame({'A': ['1', '3', '5'], 'B': ['2', '4', '6'], 'C': ['x', 'y', 'z']})
types_dict = {'A': int, 'B': float}
for col, col_type in types_dict.items():
    df[col] = df[col].astype(col_type)

如果某些列是空字符串或类似于NA的列,则keep_default_na=False是必需的,默认情况下,NA将转换为float类型的NA,这将使您最终得到str/float的混合数据类型
另一种方法是,如果您确实希望在阅读文件时为所有列指定正确的类型,并且在之后不更改它们:只读入列名(不读入行),然后使用列名填充哪些列应该是字符串

col_names = pd.read_csv('file.csv', nrows=0).columns
types_dict = {'A': int, 'B': float}
types_dict.update({col: str for col in col_names if col not in types_dict})
pd.read_csv('file.csv', dtype=types_dict)
kjthegm6

kjthegm62#

我最近遇到了同样的问题,虽然我只有一个csv文件,所以我不需要循环文件。我认为这个解决方案可以适应一个循环以及。
这里我给出了一个我使用过的解决方案,Pandas的read_csv有一个名为converters的参数,它覆盖了dtype,所以你可以利用这个特性。
示例代码如下所示:假设我们的data.csv文件包含所有float64列,除了AB是字符串列。

df = pd.read_csv('data.csv', dtype = 'float64', converters = {'A': str, 'B': str})

代码给出了转换器覆盖这两列A和B的dtype的警告,结果如预期。
关于循环遍历多个csv文件,你需要做的就是找出哪些列是例外,放入转换器中。如果文件有相似的列名模式,这很容易,否则,它会变得乏味。

iugsix8n

iugsix8n3#

您可以执行以下操作:

pd.read_csv(self._LOCAL_FILE_PATH,
            index_col=0,
             encoding="utf-8",
             dtype={
                    'customer_id': 'int32',
                    'product_id': 'int32',
                    'subcategory_id': 'int16',
                    'category_id': 'int16',
                    'gender': 'int8',
                    'views': 'int8',
                    'purchased': 'int8',
                    'added': 'int8',
                    'time_on_page': 'float16',
                 })
qqrboqgw

qqrboqgw4#

扩展@MECoskun的答案,使用转换器并同时剥离前导和白色,使转换器更加通用:

df = pd.read_csv('data.csv', dtype = 'float64', converters = {'A': str.strip, 'B': str.strip})

如果需要的话,也可以使用lstrip和rstrip来代替strip。注意,不要使用strip(),而只是strip。当然,你不能strip非字符串。

相关问题