【问题标题】:Python datatable - apply lambda to multiple columnsPython 数据表 - 将 lambda 应用于多列
【发布时间】:2021-08-23 20:56:21
【问题描述】:

我希望将一个函数应用于 Python 中的 datatable 的多个列。使用Rdata.table 会:

# columns to apply function to
x <- c('col_1', 'col_2')

# apply
df[, (x) := lapply(.SD, function(x) as.Date(x, "%Y-%m-%d")), .SDcols=x]

如何使用 Python 的datatable 做同样的事情?我对applylambdapandas 有一些了解,例如:

# create dummy data
df = pd.DataFrame({'col_1': ['2021-12-01']
                   , 'col_2': ['2021-12-02']
                   , 'col_3': ['foobar']
                   }
                  )

# columns to apply function to
x = ['col_1', 'col_2']

# apply
df[x] = df[x].apply(lambda x: pd.to_datetime(x, format='%Y-%m-%d'))

但它在 Python 的 datatable 中的等价物是什么?这是假设我坚持使用applylambda。谢谢。

edit* 我已经从 UDF 更改为标准函数 pd.to_datetime,因为我们中的一些人提到前者是不可能的,而后者是。随意使用任何示例来说明applydatatable。谢谢

【问题讨论】:

  • py-datatable 是和 Pandas 一样的第三方库;它不是“Python 的”包。如果你想知道如何使用它,你应该从阅读documentation开始。或者,如果您知道如何以这种方式解决问题,请考虑为什么您不只是使用 Pandas。
  • 目前不可能。见:github.com/h2oai/datatable/issues/1960
  • @KarlKnechtel 感谢您的链接。该文档是我审查过的众多文档之一。我找不到解决方案。我正在寻找 py-datatable 解决方案,因为它的速度快 URL @Mohammad 也感谢您的功能请求
  • 你能创建一个可重现的例子吗?然后,这里的人们可以使用 pydatatable 中的解决方案来回答。尚不支持通过 apply 使用匿名函数。将一个函数应用于多个函数是可能的;虽然不是匿名函数
  • 对于共享的示例,可以使用as_type方法,:DT[:, dt.as_type(f[:], dt.Type.date32)]。 datatable 不如 pandas 健壮(仍然缺少一些功能);随着时间的推移和社区的贡献,它只会变得更好

标签: python lambda apply py-datatable


【解决方案1】:

我最近做了一个PR,展示了在datatable 中转换列的方法;它应该很快被合并。请随时发表评论和更新。

对于题,可以直接赋值,也可以使用update方法:

from datatable import dt, f, update, Type, as_type

DT0 = dt.Frame({'col_1': ['2021-12-01']
                   , 'col_2': ['2021-12-02']
                   , 'col_3': ['foobar']
                   }
                  )

cols = ['col_1', 'col_2']

DT0
   | col_1       col_2       col_3 
   | str32       str32       str32 
-- + ----------  ----------  ------
 0 | 2021-12-01  2021-12-02  foobar
[1 row x 3 columns]

通过重新分配:

DT = DT0.copy()

DT[:, cols] = DT[:, as_type(f[cols], Type.date32)]

DT
   | col_1       col_2       col_3 
   | date32      date32      str32 
-- + ----------  ----------  ------
 0 | 2021-12-01  2021-12-02  foobar
[1 row x 3 columns]

使用直接赋值,可以将 f 表达式赋值给列;这仅适用于单个分配:

DT = DT0.copy()

DT['col_1'] = as_type(f.col_1, Type.date32)

DT['col_2'] = as_type(f.col_2, Type.date32)

DT
 
   | col_1       col_2       col_3 
   | date32      date32      str32 
-- + ----------  ----------  ------
 0 | 2021-12-01  2021-12-02  foobar
[1 row x 3 columns]

update 函数也可以工作;我喜欢这个功能,尤其是对于类似 SQL 窗口的操作,我不希望列的顺序发生变化(执行 groupby 时数据表排序):

DT = DT0.copy()

DT[:, update(col_1 = dt.as_type(f.col_1, Type.date32), 
             col_2 = dt.as_type(f.col_2, Type.date32))]
DT
   | col_1       col_2       col_3 
   | date32      date32      str32 
-- + ----------  ----------  ------
 0 | 2021-12-01  2021-12-02  foobar
[1 row x 3 columns]

注意update 是就地的;无需重新分配。 对于多列,字典可以帮助自动化该过程:

columns = {col : as_type(f[col], Type.date32) for col in cols}

print(columns)
{'col_1': FExpr<as_type(f['col_1'], date32)>,
 'col_2': FExpr<as_type(f['col_2'], date32)>}

# unpack the dictionary within the datatable brackets
DT = DT0.copy()
DT[:, update(**columns)]

DT
   | col_1       col_2       col_3 
   | date32      date32      str32 
-- + ----------  ----------  ------
 0 | 2021-12-01  2021-12-02  foobar
[1 row x 3 columns]

【讨论】:

  • DT[:, cols] = DT[:, as_type(f[cols], Type.date32)] 可能是目前最简洁的选择。我不得不问,因为我希望 R data.table 的整洁 dt[, (x) := foobar] 我遇到了字典表达式,但认为它不适用于这里。非常感谢您列出所有(当前)选项。学习的好方法。关于将更改应用于多个列与 R data.table 的截然不同的方法。为什么是这样? R data.table 的语法在技术上是不可能的吗?这应该保留给您发送的 Github 链接吗?也感谢您的链接
  • 它们是不同的语言;一方面,R 有这种延迟执行,您可以在其中传递变量并且直到很久以后才会应用;与具有急切执行的python相比。 pydatatable 所做的是尽可能地模仿 R 的数据表的语法,同时保持 Python 的惯用用法,并在 Python 的限制范围内工作。
  • 我怀疑不可能完全复制 R data.table 的语法。谢谢你们@sammywemmy
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-13
  • 1970-01-01
  • 1970-01-01
  • 2013-11-28
  • 1970-01-01
  • 2018-11-24
  • 2022-11-23
相关资源
最近更新 更多