python更新符合条件的csv单元格

2024-05-20 02:03:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在建立一个汽车销售网站预定刮擦。我有一个csv,上面有以前的广告,格式如下(为了整洁起见,大多数栏目都省略了):

id              year    first scan  last scan   active
OAG-AD-5459832  2005    31/01/2016  31/01/2016  Y
OAG-AD-12013782 2013    31/01/2016  31/01/2016  Y
OAG-AD-10487293 2015    31/01/2016  31/01/2016  Y
OAG-AD-12358252 1972    31/01/2016  31/01/2016  Y
AGC-AD-17247844 2015    31/01/2016  31/01/2016  Y

每个连续的scrape当前返回一个dict列表,如下所示:

[{'body': u'\xa0Coupe','id': u'SSE-AD-3469148', 'odo': u'288', 'adtype': u'Private Seller Car'},
 {'body': u'\xa0Coupe', 'id': u'OAG-AD-12014474', 'odo': u'0', 'adtype': u'Dealer: Demo',}]

我有三个案子要处理:

  • a) 如果刮下的广告不在csv中,请将其附加到末尾。你知道吗
  • b) 如果 在csv中,已清除的广告处于活动状态='Y',将“上次扫描”更新为 今天的日期
  • c) 对于csv中不在 已删除广告列表,更改为“N”

我目前的a)代码如下。我不知道如何有效地完成b)和c),而不为现有广告复制新行。另外-我用熊猫打开csv文件,不知道我应该继续使用它的操纵或与dicts工作。你知道吗

date = datetime.datetime.now().strftime('%d/%m/%y') #last scan date     
addb = pd.read_csv('pd output.csv') #csv of previously scraped ads
ids = addb['id'].tolist() 
addbdict = addb.to_dict(orient='records')

newads = []
for ad in adscrape:
    ad['last scan'] = date
    ad['active'] = 'Y'
    if ad['id'] not in ids:
        ad['first scan'] = date
        newads.append(ad)

addb2 = addb.append(newads)           
addb2.to_csv('pd output2.csv', index=False)

Tags: csviddatescandictadactivefirst
2条回答

不是简单地迭代新的广告,将它们添加到现有的数据框架工作中吗?
这种方法一次完成三个步骤:

addb['active'] = 'N'  # Set all ads to inactive
addb.set_index('id', inplace=True)
for ad in adscrape:
    fs = addb.loc[ad['id']]['first scan'] if ad['id'] in addb.index else date
    addb.loc[ad['id']] = pd.Series({'first scan': fs, 'last scan': date, 'active': 'Y'})

如果ad['id']存在,则它将更新last_scanactive
如果ad['id']不存在,它将创建一个新行(不确定从何处获取Year信息,因此它将是NaN

下面是我将如何使用Pandas功能实现这一点的大致方法:

import pandas as pd
import datetime
adscrape = [{'body': u'\xa0Coupe','id': u'SSE-AD-3469148', 'odo': u'288', 'adtype': u'P\
rivate Seller Car'},
            {'body': u'\xa0Coupe', 'id': u'OAG-AD-12014474', 'odo': u'0', 'adtype': u'D\
ealer: Demo',}]

date = datetime.datetime.now().strftime('%d/%m/%Y') #last scan date
addb = pd.read_csv('pd_output.csv') #csv of previously scraped ads
ids = addb['id'].tolist()
addbdict = addb.to_dict(orient='records')

newads = pd.DataFrame(adscrape)

existing = newads['id'].isin(addb['id'])
newads_to_be_appended = newads[~existing]
newads_to_be_appended['first scan'] = date
newads_to_be_appended['last scan'] = date
newads_to_be_appended['active'] = 'Y'
newads_to_be_appended['year'] = 999  # or something
addbplus = pd.concat([addb, newads_to_be_appended])

existing = addbplus['id'].isin(newads['id'])
addbplus.loc[existing,'last scan'] = date

addbplus.loc[~existing,'active'] = 'N'

addbplus.to_csv('pd_output.csv', index=False)

注意existing索引变量:第一次,它用于匹配数据库中的已删除广告(步骤a/)。第二次和第三次,情况正好相反:它将数据库与刮下的广告进行匹配(步骤b/和c/)。因此,如果您感到困惑,可以随意重命名变量。你知道吗

如果是熊猫,可能还有其他方法。
例如,我可以想象在addbnewads之间使用“outer”连接创建一个大型数据帧,并从那里开始工作。你知道吗

注意:我会避免在文件名中使用空格。它是可行的,但在某些时候更可能导致错误。使用下划线(pd_output.csv,或更合适的数据库文件名)或破折号(连字符)-分隔单词。你知道吗

相关问题 更多 >