【问题标题】:Can't convert string to float - Python Dash无法将字符串转换为浮点数 - Python Dash
【发布时间】:2020-11-19 19:42:20
【问题描述】:

我试图在 Dash 回调中将字符串转换为浮点数,但是当我运行我的代码时,我的 Dash 应用程序出现错误:lati = float(lati[-1]) ValueError: could not convert string to float: 'float64) 我在终端没有收到这个错误。

首先我需要做的是提取给定的纬度(和经度)数。因此我需要它来将其转换为字符串并拆分它,因为我找不到更好的方法来使用 pandas 从 csv 文件中获取这个数字。

输出:

# converting to string:
12    41.6796
Name: latitude, dtype: float64

# splitting:
['12', '', '', '', '41.6796']

# converting to float:
41.6796

这是实际代码:

@app.callback(Output('text-output', 'children'),
    [Input('submit-val', 'n_clicks')],
    [State('search-input', 'value')])
def updateText(n_clicks, searchVar):
    df = pd.read_csv("powerplant.csv")
    df = df[df.name == searchVar]

    # converting to string
    lati = str(df['latitude'])
    longi = str(df['longitude'])

    # splitting it
    lati = lati.split('\n', 1)
    lati = lati[0].split(' ', 4)
    longi = longi.split('\n', 1)
    longi = longi[0].split(' ', 4)

    #converting to float
    lati = float(lati[-1])
    longi = float(longi[-1]) 

我实际上在其他脚本中测试了这段代码,它工作得很好。有没有更好的方法可以提取纬度和经度数字?

数据可以从https://datasets.wri.org/dataset/globalpowerplantdatabase;下载,这里是摘录。

country,country_long,name,gppd_idnr,capacity_mw,latitude,longitude,primary_fuel,other_fuel1,other_fuel2,other_fuel3,commissioning_year,owner,source,url,geolocation_source,wepp_id,year_of_capacity_data,generation_gwh_2013,generation_gwh_2014,generation_gwh_2015,generation_gwh_2016,generation_gwh_2017,estimated_generation_gwh
AFG,Afghanistan,Kajaki Hydroelectric Power Plant Afghanistan,GEODB0040538,33.0,32.3220,65.1190,Hydro,,,,,,GEODB,http://globalenergyobservatory.org,GEODB,1009793,2017,,,,,,
AFG,Afghanistan,Mahipar Hydroelectric Power Plant Afghanistan,GEODB0040541,66.0,34.5560,69.4787,Hydro,,,,,,GEODB,http://globalenergyobservatory.org,GEODB,1009795,2017,,,,,,
ALB,Albania,Shkopet,WRI1002173,24.0,41.6796,19.8305,Hydro,,,,1963.0,,Energy Charter Secretariat,http://www.energycharter.org/fileadmin/DocumentsMedia/IDEER/IDEER-Albania_2013_en.pdf,GEODB,1021238,,,,,,,79.22851153039832
ALB,Albania,Ulez,WRI1002174,25.0,41.6796,19.8936,Hydro,,,,1958.0,,Energy Charter Secretariat,http://www.energycharter.org/fileadmin/DocumentsMedia/IDEER/IDEER-Albania_2013_en.pdf,GEODB,1021241,,,,,,,82.52969951083159

【问题讨论】:

  • 当您运行此代码但打印lati[-1] 而不是尝试转换它时,您会得到什么......输出是什么?你得到41.6796 -exactly- 还是有些不同?似乎 csv rader 没有正确转换您的列...
  • 你能从powerplant.csv添加几行示例吗?
  • 错误消息表明您以某种方式最终处理了字符串Name: latitude, dtype: float64。从你的问题中不清楚这是从哪里来的,或者你如何避免它,但也许至少这会让你朝着正确的方向前进。请edit 澄清您是否仍需要帮助。您能否包含一个显示此问题的 CSV sn-p?
  • @yossefaz 提交后动力装置终端的名称打印正确。
  • @tripleee 其实我去掉了这部分名称:纬度,dtype:float64 after 2 step:1 step: 12 41.6796 Name: latitude, dtype: float64 2 step: ['12 41.6796', 'Name: latitude, dtype: float64'] 3 step: ['12', '', '', '', '41.6796'] 4 step: 41.6796

标签: python pandas plotly-dash


【解决方案1】:

您正在查看的是一个 pandas.Series 对象,其中包含单行数据,并且您正在尝试拆分其 __repr__ 以获得该值。没有必要这样做。我不熟悉 plotly 的 Python 版本,但我看到你有一个回调,所以我把它包装成一个函数(我不确定是否存在找不到名称的情况):

import pandas as pd

def get_by_name(name):
    df = pd.read_csv('powerplants.csv')
    df = df[df['name'] == name]
    if not df.empty:
        return df[['latitude', 'longitude']].values.tolist()[0]
    return None, None


lat, lon = get_by_name('Kajaki Hydroelectric Power Plant Afghanistan')

【讨论】:

  • @Michal 这一点也不相似。我的代码是独立的 - 您需要做的就是更改 CSV 的名称
【解决方案2】:

问题在于您访问数据框中的值的方式。 Pandas 允许您访问数据而无需解析字符串表示。

您可以在一次调用.loc 中访问行和列 如果你知道你会有一个值,你可以调用squeeze方法

>>> import pandas as pd
>>> from io import StringIO
>>> # data shortened for brievity
>>> df = pd.read_csv(StringIO("""country,country_long,name,gppd_idnr,capacity_mw,latitude,longitude
... AFG,Afghanistan,Kajaki Hydroelectric Power Plant Afghanistan,GEODB0040538,33.0,32.3220,65.1190
... AFG,Afghanistan,Mahipar Hydroelectric Power Plant Afghanistan,GEODB0040541,66.0,34.5560,69.4787
... ALB,Albania,Shkopet,WRI1002173,24.0,41.6796,19.8305
... ALB,Albania,Ulez,WRI1002174,25.0,41.6796,19.8936"""))
>>> searchVar = "Ulez"
>>> df.loc[df["name"] == searchVar, "latitude"] # here you have a pd.Series
3    41.6796
Name: latitude, dtype: float64
>>> df.loc[df["name"] == searchVar, "latitude"].squeeze() # here you have a scalar
41.6796
>>> df.loc[df["name"] == searchVar, "longitude"].squeeze()
19.8936

如果由于某种原因您有多个同名的行,您将得到一个 Series 而不是一个标量。但也许这是您想要失败而不是传递模棱两可的数据的情况。

【讨论】:

  • 谢谢。它有效,但我试图将这些纬度和经度数字转换为浮点数,然后我得到一个 TypeError: cannot convert the series to lati = df.loc[df["name"] == searchVar, "latitude"].squeeze() loni = df.loc[df["name"] == searchVar, "longitude"].squeeze() lati = float(lati) loni = float(loni)
  • 看起来您有多个具有相同名称的值。在squeeze() 之后你应该已经有一个浮点数了,除非有多个值,否则你将有一个系列
  • 是的,这就是我的想法,但这是错误:ValueError: Invalid value of type 'pandas.core.series.Series' received for the 'lon' property of layout.mapbox.center 收到的值: Series([], Name: longitude, dtype: float64) 'lon' 属性是一个数字,可以指定为: - 一个 int 或 float
  • 似乎问题是一个空系列。你确定你的名字在数据框中吗?你需要在你的函数中处理这种情况
  • 是的,你说得对。现在它可以按我的意愿工作。非常感谢。祝你有美好的一天!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-11
  • 2018-04-23
  • 2015-03-25
  • 2021-12-23
  • 2017-08-12
  • 1970-01-01
相关资源
最近更新 更多