【问题标题】:A pandas dataframe column to pass as an argument of row level function to apply each value of the column to its respective row作为行级函数的参数传递的 pandas 数据框列,以将列的每个值应用于其各自的行
【发布时间】:2020-12-24 11:55:35
【问题描述】:

![在此处输入图片描述][1]

我有一个奇怪的要求,即添加类似于以下 oracle 查询的列以应用于 python 数据框。作为行级函数的参数传递的 pandas 数据框列,以将列的每个值应用于其各自的行。

select employee_id, first_name, last_name, substr(first_name, employee_id/employee_id, 3) test1 from hr.EMPLOYEES

结果已附加在以下 csv 文件中。 我想添加一个新列。所以我写了我的熊猫声明如下

EMPLOYEE.assign(test1=EMPLOYEE.FIRST_NAME.str.slice(EMPLOYEE.EMPLOYEE_ID.apply(lambda x: x/x),4))

在这段代码中,我在 EMPLOYEE.FIRST_NAME 列的切片函数中使用 EMPLOYEE.EMPLOYEE_ID。

我的意图是如果我们认为这是一个变量

FIRST_NAME="Steven"
EMPLOYEE_ID=100
FIRST_NAME[int(EMPLOYEE_ID/EMPLOYEE_ID):4]

这个的输出是 'tev'

如果我在数据框上应用相同的概念,它就不起作用。

我没有得到子字符串,而是得到了 NaN。 我的 Python 输出如下

https://i.stack.imgur.com/uZN8x.png

以下是 SQL 查询的输出。

    EMPLOYEE_ID   FIRST_NAME  LAST_NAME TEST1
0           100       Steven       King   Ste
1           101        Neena    Kochhar   Nee
2           102          Lex    De Haan   Lex
3           103    Alexander     Hunold   Ale
4           104        Bruce      Ernst   Bru
5           105        David     Austin   Dav
6           106        Valli  Pataballa   Val
7           107        Diana    Lorentz   Dia
8           108        Nancy  Greenberg   Nan
9           109       Daniel     Faviet   Dan
10          110         John       Chen   Joh
11          111       Ismael    Sciarra   Ism
12          112  Jose Manuel      Urman   Jos
13          113         Luis       Popp   Lui

我们可以通过创建一个新列来做到这一点,但是,就像在 SQL 中一样,我们可以直接做到这一点。我期待通过熊猫也一样。请帮我解决这个问题。

我的预期输出与上述相同。但是,我正在编写一个通用脚本,将 SQL 查询转换为 pandas 数据框。我被困在实现这样的场景中,其中有一列作为行级函数的参数传递。

【问题讨论】:

  • 请添加整个场景,您所说的“有列作为行级函数的参数传递的这种场景”是什么意思。 ?
  • 嗨@DaniMesejo,我已经更新了我的问题。

标签: python pandas


【解决方案1】:

试试:

res = df[['EMPLOYEE_ID', 'FIRST_NAME', 'LAST_NAME']].assign(pre=df['FIRST_NAME'].str[:3])
print(res)

输出

    EMPLOYEE_ID   FIRST_NAME  LAST_NAME  pre
0           100       Steven       King  Ste
1           101        Neena    Kochhar  Nee
2           102          Lex    De Haan  Lex
3           103    Alexander     Hunold  Ale
4           104        Bruce      Ernst  Bru
5           105        David     Austin  Dav
6           106        Valli  Pataballa  Val
7           107        Diana    Lorentz  Dia
8           108        Nancy  Greenberg  Nan
9           109       Daniel     Faviet  Dan
10          110         John       Chen  Joh
11          111       Ismael    Sciarra  Ism
12          112  Jose Manuel      Urman  Jos
13          113         Luis       Popp  Lui

要将它与str.slice 一起使用:

res = df[['EMPLOYEE_ID', 'FIRST_NAME', 'LAST_NAME']].assign(pre=df['FIRST_NAME'].str.slice(stop=3))

哪里,停止是:

stop int,切片操作的可选停止位置。

基本上一次迭代一个字符并停在位置 3(不包括在内)。

【讨论】:

  • 非常感谢您的快速回复@Dani。但是,我想知道在另一个列函数中使用列的可能性。在我的示例中,我使用了数字列除法,这意味着该列在每一行中返回 1。但是,apply 函数正在评估我的整个列并传递每一行的所有值。相反,我可以限制它按索引使用相应的行吗?
  • 您的预期输出是什么?我不明白,但您似乎想使用apply?查询的输出不是和我刚才写的pandas代码一样吗?
  • 我的预期输出与您提供的相同。但是,我正在编写一个通用脚本,将 SQL 查询转换为 pandas 数据框。我被困在实现这样的场景中,其中有一列作为行级函数的参数传递。
  • 你的目标很复杂,不是问题中所表达的,可能无法在简单的帖子中回答
  • 是的,我明白了。对不起。我的问题不是很直接。
【解决方案2】:
df[['EMPLOYEE_ID', 'FIRST_NAME', 'LAST_NAME']].apply(lambda i: i.FIRST_NAME[int(i.EMPLOYEE_ID/i.EMPLOYEE_ID):4], axis=1)

以上内容给了我答案。但它比另一个慢

%timeit EMPLOYEE.apply(lambda i: i.FIRST_NAME[int(i.EMPLOYEE_ID/i.EMPLOYEE_ID):3], axis=1)

每个循环 1.38 ms ± 58.8 µs(平均值 ± 标准偏差,7 次运行,每次 1000 个循环)

%timeit EMPLOYEE[['EMPLOYEE_ID', 'FIRST_NAME', 'LAST_NAME']].assign(pre=EMPLOYEE['FIRST_NAME'].str[1:4])

每个循环 948 µs ± 22.9 µs(7 次运行的平均值 ± 标准偏差,每次 1000 个循环)

【讨论】:

  • 谁能给我一个比我的方法更好的解决方案?
猜你喜欢
  • 2020-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
相关资源
最近更新 更多