【问题标题】:How to edit a dataframe row by row while itterating?如何在迭代时逐行编辑数据框?
【发布时间】:2020-05-21 22:05:06
【问题描述】:

所以我正在使用脚本来读取 CSV 并创建一个数据框,然后使用该数据框中的代码从该数据框中抓取价格数据。原始数据框有以下列,注意没有“价格”。

df.columns = ['Ticker TV', 'Ticker YF', 'TV Name', 'Sector', 'Industry',  'URLTV']

我已经从我的“更新”数据框中打印了以下前几个输出

 Ticker TV Ticker YF  ...  URLTV     Price
1         100D    100D.L  ...  URL       NaN
2         1GIS    1GIS.L  ...  URL       NaN
3         1MCS    1MCS.L  ...  URL       NaN
...          ...       ...  ... ...      ...
2442         ZYT     ZYT.L  ...URL       NaN
100D.L       NaN       NaN  .. NaN  9272.50
1GIS.L       NaN       NaN  ...NaN  8838.50
1MCS.L       NaN       NaN  ...NaN  5364.00

如您所见,它没有按预期工作,我想创建一个名为 Price 的新列,并用正确的代码附加每个价格,因此 100D.L 应该是 9272.50,然后当脚本迭代到下一个代码时将下一个价格值添加到 1GIS 等等。

tickerList = df['Ticker YF']
for tick in tickerList:
    summarySoup = getSummary(tick)
    currentPriceData = priceData(summarySoup)
    print('The Price of '+tick+ ' is '+str(currentPriceData))
    df.at[tick,'Price'] = currentPriceData

【问题讨论】:

    标签: python python-3.x pandas


    【解决方案1】:

    使用apply方法指定价格:

    df['Price'] = df['Ticker YF'].apply(lambda x: str(priceData(getSummary(x))))
    

    【讨论】:

    • 您好,我实现了您的代码并且运行良好,直到出现错误 def priceData(summarySoup): try: currentPriceData = summarySoup.find_all('div', {'class':'My(6px) Pos (r) smartman_Mt(6px)'})[0].find('span').text currentPriceData = currentPriceData.replace(",","") float(currentPriceData) 例外:errors.append(tick) print( "Error, "+tick) currentPriceData = 0 return currentPriceData 我在我的原始脚本中使用了这个,但现在它说tick is not defined 我该如何纠正这个?
    • 您将tick 附加到错误列表中,但您的priceData function 中无法访问tick。你可以做的是在调用时将tick 作为参数传递给这个函数。将apply方法和价格数据定义更改为apply(lambda x: str(priceData(getSummary(x),x)))def priceData(summarySoup,tick)
    【解决方案2】:

    tick 只是“Ticker YF”列中的值。所以你可以使用 enumerate 来获取索引。如果你想访问以前的价格来添加它们,你可以使用 idx-1

    tickerList = df['Ticker YF']
    for idx, tick in enumerate(tickerList):
        summarySoup = getSummary(tick)
        currentPriceData = priceData(summarySoup)
        print('The Price of '+tick+ ' is '+str(currentPriceData))
        if idx!=0:
           df.at[idx+1,'Price'] = float(currentPriceData)+float(df.at[idx,'Price'])
        else:
           df.at[idx+1,'Price'] = float(currentPriceData)
    

    一个更“优雅”的想法可能是这样的:

    df["Single_Price"]=df["Ticker YF"].apply(lambda x: priceData(getSummary(x)))
    

    获取单个价格的值。然后使用添加的价格创建下一列:

    df["Price"]=df["Ticker"].apply(lambda x: df["Single_Price"][df["Ticker"]<x["Ticker"]].sum())
    

    这会将当前行 Ticker x (df["Ticker"]

    之后,如果您不需要单个价格,您可以简单地删除它们:

    del df["Single_Price"]
    

    【讨论】:

    • 我将代码调整为 if idx!=0: df.at[idx,'Price'] = currentPriceData 因为代码会将行添加在一起产生奇怪的输出 2 1GIS 1GIS.L ... URL 5364.008838.509272.50 但现在的问题似乎是它跳过或不识别第一个条目 100D.L 的价格是 9272.50 这是第一个输出价格值 1GIS.L 的价格是 8838.50 这是第二个 1 100D 100D。 L ... URL 8838.50 但这是表格输出。正如你可以看到它附加到下一个股票代码。有什么想法吗?
    • 哦,输出似乎发生了,因为您的数据类型不是浮点数而是字符串,更改为 float(currentPriceData)+float(df.at[idx-1,'Price']) 并在else 语句也是,不知道你在那之后的进一步解释中表达了什么 ^^'
    • 表输出应该是代码 1 价格 5000 代码 2 价格 7000 代码 3 价格 8000 而是它的代码 1 价格 7000 代码 2 价格 8000,因此如果有意义的话,df 中记录的价格是代码 +1 ?
    • 啊,我明白了,那是因为 idx 从 0 开始计数,而不是从 1 开始计数。我将编辑我的第一篇文章 ;) - 顺便说一句,如果你不想像我想的那样把价格加起来:那就去吧对于 df["Price"]=df["Ticker YF"].apply(lambda x: priceData(getSummary(x))) 如下所示 - 更快更简单!
    • 我进行了 +1 调整,但它仍然没有在 DF 输出中显示第一个它没有价格所以可能是一个问题?我将代码更改为只有 df["Price"]=df["Ticker YF"].apply(lambda x: priceData(getSummary(x))) 并且它似乎破坏了显示第一个刮擦“价格100D.L 是 9272.50" 但不打印 df 并且似乎卡住了?
    猜你喜欢
    • 2014-01-08
    • 2018-01-20
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    • 2010-12-06
    • 2019-09-29
    • 2023-03-14
    相关资源
    最近更新 更多