如何根据计算将多列添加到数据框

How to add multiple columns to a dataframe based on calculations

我有一个 csv 数据集(行数 > 800 万),我将其加载到数据框中。 csv 包含如下列:

...,started_at,ended_at,...
2022-04-01 18:23:32,2022-04-01 22:18:15
2022-04-02 01:16:34,2022-04-02 02:18:32
...

我能够将数据集加载到我的数据框中,但随后我需要为每一行向数据框中添加多个计算列。换句话说,与 不同,我不希望新列的行具有相同的初始值(col 1 所有 NAN,col 2,所有“dogs”等)。

现在,我可以通过执行以下操作来添加我的专栏:

df['start_time'] = df.apply(lambda row: add_start_time(row['started_at']), axis = 1)
df['start_cat'] = df.apply(lambda row: add_start_cat(row['start_time']), axis = 1)
df['is_dark'] = df.apply(lambda row: add_is_dark(row['started_at']), axis = 1)
df['duration'] = df.apply(lamba row: calc_dur(row'[started_at'],row['ended_at']), axis = 1)

但它似乎效率低下,因为整个数据集被处理 N 次(每次调用一次)。

看来我应该能够一次性计算出所有新列,但我缺少一些概念性方法。

示例:

def calc_dur(started_at, ended_at):
  # started_at, ended_at are datetime64[ns]; converted at csv load
  diff = ended_at - started_at
  return diff.total_seconds() / 60

def add_start_time(started_at):
  # started_at is datetime64[ns]; converted at csv load
  return started_at.time()

def add_is_dark(started_at):
  # tz is pytz.timezone('US/Central')
  # chi_town is the astral lookup for Chicago
  st = started_at.replace(tzinfo=TZ)
  chk = sun(chi_town.observer, date=st, tzinfo=chi_town.timezone)
  return st >= chk['dusk'] or st <= chk['dawn']

更新 1

根据 MoRe 的信息,我能够进行必要的工作。我需要通过添加 column 名称来扩充,然后使用合并来指定索引。

  data = pd.Series(df.apply(lambda x: [
                    add_start_time(x['started_at']),
                    add_is_dark(x['started_at']),
                    yrmo(x['year'], x['month']),
                    calc_duration_in_minutes(x['started_at'], x['ended_at']),
                    add_start_cat(x['started_at'])
                  ], axis = 1))

  new_df = pd.DataFrame(data.tolist(),
                        data.index, 
                        columns=['start_time','is_dark','yrmo',
                                 'duration','start_cat'])

  df = df.merge(new_df, left_index=True, right_index=True)
import pandas as pd
data = pd.Series(dataframe.apply(lambda x: [function1(x[column_name]), function2(x[column_name)], function3(x[column_name])], axis = 1))
pd.DataFrame(data.tolist(),data.index)

如果我没看错你的意思,这就是你的答案。但在一切之前请使用 Swifter pip :) 首先按列表创建一个系列并将其转换为列...

swifter 是一个简单的库(至少我认为它很简单),只有一个有用的方法:apply

import swifter
data.swifter.apply(lambda x: x+1)

它使用并行方式来提高大型数据集的速度...在小型数据集中,它不是很好,甚至更糟

https://pypi.org/project/swifter/