pandas-批量运算,map

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pandas-批量运算,map相关的知识,希望对你有一定的参考价值。

参考技术A pandas批量运算主要分按行,按列跟按dataframe计算。一般来说,是for循环的替代算法。
批量运算一般是用自定义def或者自带函数,根据def参数的情况就可以分为单参数和多参数,先说按列的map函数
map:
单列:
dataframe['列名'].map(函数名)
比如df['code'].map(savetomysql)
其中:
df['code']:dataframe里的code这一列
savetomysql是我自定义的def,它应该有一个参数,或者有多个参数但其他参数都有默认值。def savetomysql(code,date=2...)

多列:
list(map(lambda x, y: 函数(x, y), dataframe['列名1'], dataframe['列名2']))
比如list(map(lambda x, y: getdata(x, y), df['code'], df['date']))
若有其他固定参数,放在lambda里面:list(map(lambda x, y,z=5: getdata(x, y,z), df['code'], df['date']))
特别说明的是getdata返回值是多个的话,可以用list返回,然后变成dataframe拼接到原始数据中。
比如:
getdata return [A,B,C],列名是‘A’,‘B’,‘C’
df是原始dataframe
rate = list(map(lambda x, y: getdata(x, y), ori['code'], ori['date']))
name = 'code,date,A,B,C'
col = name.split(',')
temp = pd.DataFrame(data=rate, columns=col)
df1= pd.merge(df, temp, on=['code', 'date']) #加列
df1就是根据两列生成新的dataframe,我经常这么做。

pandas 'DataFrame' 对象没有属性 'map'

【中文标题】pandas \'DataFrame\' 对象没有属性 \'map\'【英文标题】:pandas 'DataFrame' object has no attribute 'map'pandas 'DataFrame' 对象没有属性 'map' 【发布时间】:2019-01-15 14:33:36 【问题描述】:

我有两个 df - df_a 和 df_b,

# df_a
number    cur    code
1000      USD    700
2000      USD    800
3000      USD    900

# df_b
number    amount    deletion code
1000      0.0       L        700
1000      10.0      X        700
1000      10.0      X        700
2000      20.0      X        800
2000      20.0      X        800
3000      0.0       L        900
3000      0.0       L        900

我想将df_adf_b 合并,

df_a = df_a.merge(df_b.loc[df_b.deletion != 'L'], how='left', on=['number', 'code'])

另外,在合并结果df_a 中创建一个名为deleted 的标志,它具有三个可能的值——完整、部分和无;

full - 如果所有行都与特定的number 值关联,则有deletion = L;

partial - 如果某些行与特定的number 值相关联,则具有deletion = L;

none - 没有与特定 number 值关联的行,有 deletion = L;

在进行合并时,不应考虑来自df_bdeletion = L 的行;所以结果看起来像,

 number    amount    deletion    deleted    cur    code
 1000      10.0      X           partial    USD    700
 1000      10.0      X           partial    USD    700
 2000      20.0      X           none       USD    800
 2000      20.0      X           none       USD    800
 3000      0.0       NaN         full       USD    900

我试过了,

g = df_b['deletion'].ne('L').groupby([df_b['number'], df_b['code']])
m1 = g.any()
m2 = g.all()

d1 = dict.fromkeys(m1.index[m1 & ~m2], 'partial')
d2 = dict.fromkeys(m2.index[m2], 'full')

d = **d1, **d2
df_a = df_a.merge(df_b.loc[df_b.deletion != 'L'], how='left', on=['code', 'number'])

df_a['deleted'] = df_a[['number', 'code']].map(d).fillna('none')

但我遇到了一个错误,

AttributeError: 'DataFrame' object has no attribute 'map'

似乎df 没有map 功能,所以我想知道是否有任何替代方法可以实现这一点。

【问题讨论】:

@jpp sry,再次更新,我试图df_a['deleted'] = df_a[['number', 'code']].map(d).fillna('none'),导致错误,所以想知道是否有其他方法可以做同样的事情。 这能回答你的问题吗? AttributeError: 'DataFrame' object has no attribute 'map' 【参考方案1】:

pd.DataFrame 对象没有map 方法。您可以改为从两列构建索引并将pd.Index.map 与函数一起使用:

df_a['deleted'] = df_a.set_index(['number', 'code']).index.map(d.get)
df_a['deleted'] = df_a['deleted'].fillna('none')

兼容性说明

对于大于 0.25 的 Pandas 版本,您可以直接将 pd.Index.map 与字典一起使用,即使用 d 而不是 d.get

对于以前的版本,我们使用d.get 而不是d,因为与pd.Series.map 不同,pd.Index.map 不直接接受字典。但它可以接受dict.get 之类的函数。另请注意,我们将fillna 操作分开,因为pd.Index.map 返回一个数组而不是一个系列。

【讨论】:

以上是关于pandas-批量运算,map的主要内容,如果未能解决你的问题,请参考以下文章

Pandas数据类型运算

Pandas的对齐运算和函数

Python: Pandas运算的效率探讨以及如何选择高效的运算方式

pandas学习笔记四:运算方法和运算工具

vectorize向量化函数对DataFrame中值进行复杂运算

Python机器学习入门——科学计算库(Pandas)