Py学习  »  Python

如何在pandas python中为字符串创建汇总列[duplicate]

Asher • 4 年前 • 977 次点击  

我有一本这样的字典: di = {1: "A", 2: "B"}

我想将其应用于数据帧的“col1”列,类似于:

     col1   col2
0       w      a
1       1      2
2       2    NaN

得到:

     col1   col2
0       w      a
1       A      2
2       B    NaN

我怎样才能做到最好呢?出于某种原因,与此相关的google术语只显示了如何从dict创建列的链接,反之亦然:-/

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/43963
 
977 次点击  
文章 [ 7 ]  |  最新文章 4 年前
U10-Forward
Reply   •   1 楼
U10-Forward    5 年前

或做 apply :

df['col1'].apply(lambda x: {1: "A", 2: "B"}.get(x,x))

演示:

>>> df['col1']=df['col1'].apply(lambda x: {1: "A", 2: "B"}.get(x,x))
>>> df
  col1 col2
0    w    a
1    1    2
2    2  NaN
>>> 
Amirhos Imani
Reply   •   2 楼
Amirhos Imani    6 年前

更具本土特色的熊猫方法是应用如下替换功能:

def multiple_replace(dict, text):
  # Create a regular expression  from the dictionary keys
  regex = re.compile("(%s)" % "|".join(map(re.escape, dict.keys())))

  # For each match, look-up corresponding value in dictionary
  return regex.sub(lambda mo: dict[mo.string[mo.start():mo.end()]], text) 

一旦定义了函数,就可以将其应用到数据文件中。

di = {1: "A", 2: "B"}
df['col1'] = df.apply(lambda row: multiple_replace(di, row['col1']), axis=1)
wordsforthewise
Reply   •   3 楼
wordsforthewise    5 年前

DSM已经得到了公认的答案,但是编码似乎并不适合所有人。以下是一款适用于当前版本的熊猫(截至2018年8月,0.23.4):

import pandas as pd

df = pd.DataFrame({'col1': [1, 2, 2, 3, 1],
            'col2': ['negative', 'positive', 'neutral', 'neutral', 'positive']})

conversion_dict = {'negative': -1, 'neutral': 0, 'positive': 1}
df['converted_column'] = df['col2'].replace(conversion_dict)

print(df.head())

你会看到它看起来像:

   col1      col2  converted_column
0     1  negative                -1
1     2  positive                 1
2     2   neutral                 0
3     3   neutral                 0
4     1  positive                 1

文档为 pandas.DataFrame.replace are here .

Nico Coallier
Reply   •   4 楼
Nico Coallier    6 年前

如果要在数据数据帧中重新映射多个列,则添加此问题:

def remap(data,dict_labels):
    """
    This function take in a dictionnary of labels : dict_labels 
    and replace the values (previously labelencode) into the string.

    ex: dict_labels = {{'col1':{1:'A',2:'B'}}

    """
    for field,values in dict_labels.items():
        print("I am remapping %s"%field)
        data.replace({field:values},inplace=True)
    print("DONE")

    return data

希望它对某人有用。

干杯

unutbu
Reply   •   5 楼
unutbu    10 年前

你的问题有点模棱两可。至少有 两种解释:

  1. 钥匙在 di 参考索引值
  2. 钥匙在 参照 df['col1'] 价值观
  3. 钥匙在 参考索引位置(不是OP的问题,而是为了好玩而抛出的。)

以下是每种情况的解决方案。


案例1: 如果 是指索引值,然后可以使用 update 方法:

df['col1'].update(pd.Series(di))

例如,

import pandas as pd
import numpy as np

df = pd.DataFrame({'col1':['w', 10, 20],
                   'col2': ['a', 30, np.nan]},
                  index=[1,2,0])
#   col1 col2
# 1    w    a
# 2   10   30
# 0   20  NaN

di = {0: "A", 2: "B"}

# The value at the 0-index is mapped to 'A', the value at the 2-index is mapped to 'B'
df['col1'].update(pd.Series(di))
print(df)

产量

  col1 col2
1    w    a
2    B   30
0    A  NaN

我修改了你原帖中的值,这样就更清楚了 更新 正在做。 注意钥匙是如何进入的 与索引值关联。索引值的顺序——即,索引 位置 --没关系。


案例2: 如果钥匙在 参照 DF[COL1′] 值,然后@danallan和@dsm显示如何使用 replace :

import pandas as pd
import numpy as np

df = pd.DataFrame({'col1':['w', 10, 20],
                   'col2': ['a', 30, np.nan]},
                  index=[1,2,0])
print(df)
#   col1 col2
# 1    w    a
# 2   10   30
# 0   20  NaN

di = {10: "A", 20: "B"}

# The values 10 and 20 are replaced by 'A' and 'B'
df['col1'].replace(di, inplace=True)
print(df)

产量

  col1 col2
1    w    a
2    A   30
0    B  NaN

注意,在这种情况下,如何在 已更改为匹配 价值观 在里面 DF[COL1′] .


案例3: 如果钥匙在 参考索引位置,然后可以使用

df['col1'].put(di.keys(), di.values())

自从

df = pd.DataFrame({'col1':['w', 10, 20],
                   'col2': ['a', 30, np.nan]},
                  index=[1,2,0])
di = {0: "A", 2: "B"}

# The values at the 0 and 2 index locations are replaced by 'A' and 'B'
df['col1'].put(di.keys(), di.values())
print(df)

产量

  col1 col2
1    A    a
2   10   30
0    B  NaN

在这里,第一行和第三行被修改了,因为 0 2 ,它使用python基于0的索引引用第一个和第三个位置。

JohnE
Reply   •   6 楼
JohnE    5 年前

map 可以比快得多 replace

如果你的字典有两个以上的键,使用 地图 可以比快得多 代替 . 此方法有两种版本,具体取决于词典是否详尽地映射了所有可能的值(以及是否希望不匹配项保留其值或转换为nans):

穷举映射

在这种情况下,形式非常简单:

df['col1'].map(di)       # note: if the dictionary does not exhaustively map all
                         # entries then non-matched entries are changed to NaNs

虽然 地图 最常用的函数是它的参数,它可以替代地使用字典或系列: Documentation for Pandas.series.map

非穷举映射

如果有非穷尽映射,并且希望保留非匹配的现有变量,则可以添加 fillna :

df['col1'].map(di).fillna(df['col1'])

正如@jpp在这里的回答: Replace values in a pandas series via dictionary efficiently

基准点

在Pandas 0.23.1版中使用以下数据:

di = {1: "A", 2: "B", 3: "C", 4: "D", 5: "E", 6: "F", 7: "G", 8: "H" }
df = pd.DataFrame({ 'col1': np.random.choice( range(1,9), 100000 ) })

和测试 %timeit ,看起来 地图 大约比 代替 .

注意你的加速 地图 会因你的数据而有所不同。最大的加速似乎是大词典和详尽的替代品。更多的基准测试和讨论请参见@jpp answer(链接在上面)。

Winand DSM
Reply   •   7 楼
Winand DSM    5 年前

你可以使用 .replace 。例如:

>>> df = pd.DataFrame({'col2': {0: 'a', 1: 2, 2: np.nan}, 'col1': {0: 'w', 1: 1, 2: 2}})
>>> di = {1: "A", 2: "B"}
>>> df
  col1 col2
0    w    a
1    1    2
2    2  NaN
>>> df.replace({"col1": di})
  col1 col2
0    w    a
1    A    2
2    B  NaN

或者直接在 Series ,即 df["col1"].replace(di, inplace=True) .