gpt4 book ai didi

python - 根据另一列的掩码修改 Pandas 数据框列的符号?

转载 作者:太空宇宙 更新时间:2023-11-03 20:01:02 25 4
gpt4 key购买 nike

我正在处理从 NASA 火球数据 API ( https://cneos.jpl.nasa.gov/fireballs/ ) 导入的纬度/经度数据

  • lat/lon 数据只有正值
  • 它们的方向(北/南和东/西)位于不同的列中,称为lat-dir/lon-dir
  • 数据框如下。
  • 现在我想要:
  • 如果“lat-dir”== 'S',则将任何 lat 值转换为负数(乘以 -1)
  • 如果“lon-dir”== 'W',则将 lon 值转换为负数

以下大致是我创建数据框的方式:

import requests 
import pandas as pd

response = requests.get('https://ssd-api.jpl.nasa.gov/fireball.api')
j = response.json()
df = pd.DataFrame.from_dict(j[u'data'])

print( j[u'fields'] )

[u'date', u'energy', u'impact-e', u'lat', u'lat-dir', u'lon', u'lon-dir', u'alt', u'vel']

print( df.head() )

0 1 2 3 4 5 6 7 8
0 2019-12-06 10:19:57 4.6 0.15 3.3 S 37.7 W 19.5 None
1 2019-12-03 06:46:27 4.2 0.14 5.6 N 52.2 W 61.5 None
2 2019-11-28 20:30:54 2.7 0.095 35.7 N 31.7 W 35 13.0
3 2019-11-28 13:22:10 2.6 0.092 None None None None None None
4 2019-11-28 11:55:02 2.5 0.089 22.1 S 25.7 E 22.5 24.7
<小时/>

我尝试过的代码行:

尝试使用df.apply() - 尽管通过我的搜索,我认为您无法轻松地以这种方式引用两列...

    df['lat'] = df['lat'].apply(lambda x: x * -1 if (df['lat-dir'][x] == 'S'))
<小时/>
    for i, row in df.iterrows():
if (row['lat-dir'] == 'S'):
df['lat'][i].apply(lambda x: x*-1)

为此,我得到“numpy.float64”对象没有属性“apply”?

<小时/>

尝试使用屏蔽:

    if( df['lon-dir'] == 'W'):
df['lon'] * -1
<小时/>

但坦率地说,我很困惑接下来要做什么关于敷面膜的事情。

编辑:

dfDate['lat'] = dfDate['lat'].apply(lambda row: row['lon'] * -1 , axis = 1 )

根据评论也尝试过这一点。

最佳答案

是的,通过以下任一方式:

A) 使用矢量化蒙版==没有矢量化; .eq(...)是。对于矢量化表达式,请使用 dfDate['lon-dir'].eq('W') 。然后对这些行上的“lon”列取反。

B) 使用 apply()按行:dfDate['lon'] = dfDate.apply(lambda row: ..., axis=1) - 在你的 lambda 中选择性地否定 row['lon']基于值row['lon-dir'] - 你的原因apply调用失败是您需要应用于整个列/系列,而不是单个条目。所以:df['lat'].apply(lambda: ..., axis=1)

lat-dir/lon-dir本质上是符号列,您可以在读入它们时将它们转换为+1/-1。

代码:

首先是您需要修复的代码的一些问题:

  1. 不要使用 u'...' 符号。假设您使用的是 Python 3.x,不需要 u'...',文本现在在 3.x 中默认为 unicode。如果您不使用 Python 3.x,您确实应该立即切换,2.x 将于 2020 年 1 月 1 日停止使用。
  2. 将 JSON 列名称传递到数据框上,让您的生活变得轻松:
    • df.columns = j['fields']
  3. 通过传递 response.json() 读取 JSON进入pd.DataFrame.from_dict()是一种痛苦;您的数据框列变成字符串/“对象”,而不是将浮点列转换为 float 。理想情况下,我们应该使用 pandas.read_json(..., dtype=...)出于这个和其他方便的原因。
  4. 您需要转换数字列上的数据类型(例如字符串 -> float ),并且这也会自动转换 Python None -> Pandas /numpy nan (为了矢量化代码,我们将优雅地编写处理 nan 而不是不断抛出烦人的 TypeError: unsupported operand type(s) for *: 'NoneType' and 'int' )。您可以[使用 astype(...) 执行此操作, pd.to_numeric()df.fillna(value=pd.np.nan, inplace=True)
  5. 实际上,由于下面列出的多种原因,这些 nan 条目将继续成为一种痛苦(例如整数不断被强制返回 float ),因此您可能想要删除或至少暂时忽略 nan 行 通过这样做:
    • df2 = df.dropna(how='any', inplace=False) # 可能不与..., inplace=True 。请注意,这会保留行索引,因此您始终可以将处理 df2 的结果插入到最后的 df 中。阅读dropna doc 并找出您想要在哪个确切点删除 nan。
    • 请注意,“vel”列实际上还有其他我们想要忽略的 nan,您需要弄清楚这一点,或者暂时忽略它们:例如做df2 = df[['date','energy','impact-e','lat','lat-dir','lon','lon-dir']].dropna(how='any', inplace=False)

解决方案

  • 将纬度/经度列转换为 +/-1 符号的几种方法:

    A1)如果你想要“正确”的、知道纳米的方式,并且不会被纳米窒息......

  •     df2['lat'] = df2['lat-dir'].map({'N': +1, 'S': -1})
    df2['lon'] = df2['lon-dir'].map({'E': +1, 'W': -1})
    A2) ...or a fast-and-dirty way:
        (-1) ** df2['lat-dir'].eq('S')
    (-1) ** df2['lon-dir'].eq('W')

    B) 但是您可以在一行中完成这一切apply()功能:

    def fixup_latlon_signs(row):
    row['lat'] = row['lat'] * (-1) ** (row['lat-dir'] == 'S')
    row['lon'] = row['lon'] * (-1) ** (row['lon-dir'] == 'W')
    return row

    df2.apply(fixup_latlon_signs, axis=1)

    # Then insert the non-NA rows we processed back into the parent dataframe:
    df.update(df2)

    # Strictly we can drop 'lat-dir','lon-dir' now...

    关于python - 根据另一列的掩码修改 Pandas 数据框列的符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59232584/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com