根据其他字段的计算,在 pandas 数据框中一次创建两个新字段

Posted

技术标签:

【中文标题】根据其他字段的计算,在 pandas 数据框中一次创建两个新字段【英文标题】:Create two new fields at once in pandas dataframe based off of calculations of other fields 【发布时间】:2020-08-23 05:13:15 【问题描述】:

我将一系列 csv 文件作为数据框进行迭代,最终将它们全部写入一个通用的 excel 工作簿。

在众多文件之一中,十进制 GPS 值(纬度、经度)分为两列(df[4]df[5]),我将其转换为度-分-秒。该方法返回一个元组,我试图将其停放在原始数据帧同一行中的两个名为 dmslatdmslon 的新字段中:

def convert_dd_to_dms(lat, lon):
    # does the math here
    return dmslat, dmslon

csv_dir = askdirectory()  # tkinter directory picker
os.chdir(csv_dir)
for f in glob.iglob("*.csv"):
    (csv_path, csv_name) = os.path.split(f)
    (csv_prefix, csv_ext) = os.path.splitext(csv_name)
    if csv_prefix[-3:] == "loc":
        df = pd.read_csv(f)
        df['dmslat'] = None
        df['dmslon'] = None
        for i, row in df.iterrows():
            fixed_coords = convert_dd_to_dms(row[4], row[5])
            row['dmslat'] = fixed_coords[0]
            row['dmslon'] = fixed_coords[1]
        print(df)
# process the other files 

因此,当我使用 print() 语句时,我可以看到坐标已正确计算,但它们并未提交给 dmslat/dmslon 字段。

我也尝试在行迭代器中分配新字段,但由于我处于行规模,它最终每次都会用新的计算值覆盖整个列。

如何让结果(简洁地)填充列?

【问题讨论】:

【参考方案1】:

df.iterrows() 似乎会导致每一行的“副本”,因此当您添加/更新列“dmslat”和“dmslon”时,您正在修改副本,而不是原始数据帧。这可以通过在分配后打印“行”来确认。您将看到行项目已成功更新,但更改未反映在原始数据框中。

要修改原始数据框,您可以这样修改代码:

        for i, row in df.iterrows():
            fixed_coords = convert_dd_to_dms(row[4], row[5])
            df.loc[i, 'dmslat'] = fixed_coords[0]
            df.loc[i, 'dmslon'] = fixed_coords[1]
        print(df)

使用df.loc 保证对原始数据帧进行更改。

【讨论】:

我明白了。 Null 值很好,因为在迭代新数据以构建几何层(shapefile 等)时,我可以轻松地忽略它们。感谢您的超快速响应。 您也可以在没有循环的情况下完成此操作。见***.com/questions/14059094/…。【参考方案2】:

我认为你最好使用apply 而不是iterrows

这是一个基于apply 的解决方案。我用一个名为“foo”的函数替换了您的位置计算,该函数从两个字段“a”和“b”到“a”和“b”的新值进行了一些任意计算。

df = pd.DataFrame("a": range(10), "b":range(10, 20))
def foo(row):
    return (row["a"] + row["b"], row["a"] * row["b"])

new_df = df.apply(foo, axis=1).apply(pd.Series)

在上面的代码块中,应用 'foo' 会为每一行返回一个元组。再次使用 applypd.Series 会将其转换为数据框。

df[["a", "b"]] = new_df
df.head(3) 

    a   b
0   10  0
1   23  132
2   38  336

【讨论】:

以上是关于根据其他字段的计算,在 pandas 数据框中一次创建两个新字段的主要内容,如果未能解决你的问题,请参考以下文章

如何从 pandas 数据框中的大型每日 JSON 数据集计算平均月值?

如何根据记录中其他 4 个字段的布尔运算符有效地更新数据框中的字段?

SQL中一次插入多条数据

Pandas 从列表列表中一次添加多个新列

根据熊猫数据框中其他列的条件和值创建新列[重复]

如何在 Pandas DataFrame 中一次获取多列的值计数?