【问题标题】:Apply function to create multiple columns in pandas应用函数在熊猫中创建多列
【发布时间】:2020-12-18 08:36:19
【问题描述】:

正如标题所示,我正在寻找一种方法来为数据框中的每一行应用一个函数,并针对一列创建多个新列。

所以我的意思是,我有一个包含不同城市名称的 df。现在我想创建 2 个新行,其中包含人口规模、国家、成立日期以及可能的更多信息。

我有一个以 json 格式返回这些信息的 API。到现在为止还挺好。 我目前正在做的是使用 for 循环来遍历 df,进行 api 调用,然后使用 iloc 设置列...它不是很好或效率很高。

我想知道是否可以使用应用/转换函数产生类似的结果。

我目前的解决方案:

for index, row in data.iterrows():
    print("--------------------->" + str(index))
    try:
        infos = cityInfo.download(row["city"],row["zip"])
    except:
        break
    if len(infos) == 0:
        print("City not found!")
    else:
        data["pop"].iloc[index] = infos["population"]
        data["country"].iloc[index] = infos["country"]
        data["founding"].iloc[index] = infos["foundingDate"

我很高兴得到任何帮助或提示

【问题讨论】:

  • 请展示一些最小的例子来重现您的输入和预期的输出。

标签: python pandas apply


【解决方案1】:

来自 Pandas 文档:

你不应该修改你正在迭代的东西。这不能保证在所有情况下都有效。根据数据类型,迭代器返回一个副本而不是一个视图,写入它不会有任何效果。

首先,我将遍历索引并引用该数据框。 (我没有写在你的 try-except 语句中,但如果需要,可以添加)。

我假设你的 API 做了这样的事情:

class cityInfoAPIDummy:
def __init__(self):
    self.data = pd.DataFrame(columns=["city","zip","population","country","foundingDate"],data=[["london","NE1","100000","UK","ages ago"],["birmingham","B","50000","UK","less long ago"]])
def download(self,city,z):
    return self.data[self.data["city"]==city][self.data["zip"]==z]
        
    

使用 apply() 函数执行您想要执行的操作的代码如下所示:

def get_info(city,z,field):
    cityInfo=cityInfoAPIDummy()

    infos = cityInfo.download(city,z)

    if len(infos)==0:
        print("City not found")
        return ""
    else:
        return infos[field].values[0]

if __name__ == "__main__":
    # assuming some dummy data in the format you were after
    data = pd.DataFrame(columns=["city","zip"],data=[["london","NE1"],["birmingham","B"]])
    data["pop"] = data.apply( lambda x: get_info(x["city"],x["zip"],"population") ,axis=1)
    data["country"] = data.apply(lambda x: get_info(x["city"],x["zip"],"country"),axis=1)
    data["founding"] = data.apply(lambda x: get_info(x["city"],x["zip"],"foundingDate"),axis=1)

print(data)

我希望这会有所帮助,但如果它是自定义 API,则很难知道该 API 为您提供什么服务。

【讨论】:

    【解决方案2】:

    对于涉及这里没有人了解的 API 的问题,不要期望得到好的答案。在循环的每次迭代中调用 API 可能是缓慢的部分。如果您的 API 不允许在一次调用中下载所有信息,您可能无法大幅提高性能。 此外,应用/转换(在获取行时)将执行基本相同的操作,调用 API [no.行数] 次。取列,这些方法不会同时取两列。

    【讨论】:

      猜你喜欢
      • 2013-04-20
      • 1970-01-01
      • 1970-01-01
      • 2019-07-30
      • 2016-06-16
      • 2015-01-09
      • 2023-01-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多