【问题标题】:Changing CSV files in python在 python 中更改 CSV 文件
【发布时间】:2013-09-02 08:01:20
【问题描述】:

我有一堆带有 4 行标题的 CSV 文件。在这些文件中,我想根据第二列中的值更改第六列中的值。例如,如果名称PRODUCT 下的第二列是Banana,我想将TIME 下同一行中的值更改为10m。如果产品是Apple,我希望时间是15m等等。

When    12:07           
Area    Produce             
Store Name   FF             
Eatfresh                    
PN  PRODUCT NUMBER  INV ENT TIME
1    Banana 600000                5m
2    Apple  400000       F4        8m                                              
3    Pair                       6m
4    Banana 4000     G3            7m
5    Watermelon 700000          13m
6    Orange 12000               2m
7    Apple  1650000         6m

期望的输出

When    12:07           
Area    Produce             
Store Name   FF             
Eatfresh                    
PN  PRODUCT NUMBER  INV ENT TIME
1    Banana 600000                10m
2    Apple  400000       F4        15m                                              
3    Pair                       6m
4    Banana 4000     G3            10m
5    Watermelon 700000          13m
6    Orange 12000               2m
7    Apple  1650000         15m

我想将它们全部输出到目录调用NTime。到目前为止,这是我所拥有的,但是对于编码而言,我并不是很了解,并且一直停留在如何进行实际更改上。我找到了Python/pandas idiom for if/then/else,看起来和我想做的差不多,但我不完全明白发生了什么。

import pandas as pd
import glob
import os

fns = glob.glob('*.csv') 
colname1 = 'PRODUCT'
colname2 = 'TIME'

for csv in fns:
    s = pd.read_csv(csv, usecols=[colname1], squeeze=True, skiprows=4, header=0)



    with open(os.path.join('NTime', fn), 'wb') as f:

有人可以帮我吗?

【问题讨论】:

    标签: python csv pandas glob


    【解决方案1】:

    您可以通过 groupbyreplacedict 的组合来完成此操作

    In [76]: from pandas import DataFrame
    
    In [77]: fruits = ['banana', 'apple', 'pear', 'banana', 'watermelon', 'orange', 'apple']
    
    In [78]: times = ['5m', '8m', '6m', '7m', '13m', '2m', '6m']
    
    In [79]: time_map = {'banana': '10m', 'apple': '15m', 'pear': '5m'}
    
    In [80]: df = DataFrame({'fruits': fruits, 'time': times})
    Out[80]:
           fruits time
    0      banana   5m
    1       apple   8m
    2        pear   6m
    3      banana   7m
    4  watermelon  13m
    5      orange   2m
    6       apple   6m
    
    In [81]: def replacer(g, time_map):
       ....:     tv = g.time.values
       ....:     return g.replace(to_replace=tv, value=time_map.get(g.name, tv))
    
    In [82]: df.groupby('fruits').apply(replacer, time_map)
    Out[82]:
           fruits time
    0      banana  10m
    1       apple  15m
    2        pear   5m
    3      banana  10m
    4  watermelon  13m
    5      orange   2m
    6       apple  15m
    

    你说你是编程新手,所以我会解释发生了什么。

    1. df.groupby('fruits') 使用fruits 列的值将DataFrame 拆分为子集(即DataFrames 或Series 对象)。

    2. apply 方法将一个函数应用于上述每个子集并连接结果(如果需要)。

    3. replacer 是“神奇”发生的地方:每个组的 time 值被替换 (to_replace) 为在 time_map 中定义的 值。 dicts 的 get 方法允许您在不存在您要搜索的键(在本例中为水果名称)时提供默认值。 nan 通常用于此目的,但在这里我实际上只是使用已经存在的时间,如果在 time_map dict 中没有为它定义新的时间。

      李>

    需要注意的一点是我使用了g.name。这通常不作为DataFrames 上的属性存在(如果您愿意,您当然可以自己定义),但是在那里您可以执行可能需要组名的计算。在这种情况下,这就是您在应用函数时正在查看的“当前”结果。

    如果您对每个水果都有一个新值,或者您手动写入旧值,您可以将其缩短为单行:

    In [130]: time_map = {'banana': '10m', 'apple': '15m', 'pear': '5m', 'orange': '10m', 'watermelon': '100m'
    }
    
    In [131]: s = Series(time_map, name='time')
    
    In [132]: s[df.fruits]
    Out[132]:
    fruits
    banana         10m
    apple          15m
    pear            5m
    banana         10m
    watermelon    100m
    orange         10m
    apple          15m
    Name: time, dtype: object
    
    In [133]: s[df.fruits].reset_index()
    Out[133]:
           fruits  time
    0      banana   10m
    1       apple   15m
    2        pear    5m
    3      banana   10m
    4  watermelon  100m
    5      orange   10m
    6       apple   15m
    

    【讨论】:

      【解决方案2】:

      假设您的数据在 Pandas DataFrame 中并且看起来像这样:

      PN  PRODUCT NUMBER  INV ENT TIME
      1    Banana 600000                10m
      2    Apple  400000       F4        15m                                              
      3    Pair                       6m
      4    Banana 4000     G3            10m
      5    Watermelon 700000          13m
      6    Orange 12000               2m
      7    Apple  1650000         15m
      

      然后您应该能够使用这样的简单循环根据另一列(同一行)中的值来操作一列中的值:

      for numi, i in enumerate(df["PRODUCT"]):
          if i == "Banana":
              df["TIME"][numi] = "10m"
          if i == "Apple":
              df["TIME"][numi] = "15m"
      

      代码首先遍历数据框列“PRODUCT”的行,行值存储为 i,行号存储为 numi。然后,它使用 if 语句来识别 Product 列中的不同兴趣级别。对于那些感兴趣级别的行(例如“香蕉”或“苹果”),它使用行号来更改同一行中另一列的值。

      有很多方法可以做到这一点,根据您的数据大小和您想要更改的级别(在本例中为“产品”)的数量,这不一定是最有效的方法.但是由于您是初学者,因此这可能是您开始的一种很好的基本方法。

      【讨论】:

      猜你喜欢
      • 2020-12-20
      • 1970-01-01
      • 1970-01-01
      • 2020-07-06
      • 2017-03-11
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      • 1970-01-01
      相关资源
      最近更新 更多