python pandas用数字替换数据框中的字符串
Posted
技术标签:
【中文标题】python pandas用数字替换数据框中的字符串【英文标题】:python pandas replacing strings in dataframe with numbers 【发布时间】:2013-06-11 11:33:38 【问题描述】:有没有办法使用映射函数或更好的方法来替换整个数据框中的值?
我只知道如何对系列进行映射。
我想用数字替换 'test' 和 'set' 列中的字符串 例如设置=1,测试=2
这是我的数据集的示例:(原始数据集非常大)
ds_r
respondent brand engine country aware aware_2 aware_3 age tesst set
0 a volvo p swe 1 0 1 23 set set
1 b volvo None swe 0 0 1 45 set set
2 c bmw p us 0 0 1 56 test test
3 d bmw p us 0 1 1 43 test test
4 e bmw d germany 1 0 1 34 set set
5 f audi d germany 1 0 1 59 set set
6 g volvo d swe 1 0 0 65 test set
7 h audi d swe 1 0 0 78 test set
8 i volvo d us 1 1 1 32 set set
最终结果应该是
ds_r
respondent brand engine country aware aware_2 aware_3 age tesst set
0 a volvo p swe 1 0 1 23 1 1
1 b volvo None swe 0 0 1 45 1 1
2 c bmw p us 0 0 1 56 2 2
3 d bmw p us 0 1 1 43 2 2
4 e bmw d germany 1 0 1 34 1 1
5 f audi d germany 1 0 1 59 1 1
6 g volvo d swe 1 0 0 65 2 1
7 h audi d swe 1 0 0 78 2 1
8 i volvo d us 1 1 1 32 1 1
【问题讨论】:
【参考方案1】:您可以从column
值本身构建dictionary
并填充如下
x=df['Item_Type'].value_counts()
item_type_mapping=
item_list=x.index
for i in range(0,len(item_list)):
item_type_mapping[item_list[i]]=i
df['Item_Type']=df['Item_Type'].map(lambda x:item_type_mapping[x])
【讨论】:
【参考方案2】:替换数据框中任何值的最简单方法:
df=df.replace(to_replace="set",value="1")
df=df.replace(to_replace="test",value="2")
希望这会有所帮助。
【讨论】:
【参考方案3】:要将“volvo”、“bmw”等字符串转换为整数,首先将其转换为数据帧,然后将其传递给 pandas.get_dummies()
df = DataFrame.from_csv("myFile.csv")
df_transform = pd.get_dummies( df )
print( df_transform )
更好的选择:将字典传递给 pandas 系列 (df.myCol) 的 map() (例如通过指定列品牌)
df.brand = df.brand.map( 'volvo':0 , 'bmw':1, 'audi':2 )
【讨论】:
【参考方案4】:来自@Ishnark 的df.replace(to_replace=['set', 'test'], value=[1, 2])
对接受的答案发表评论。
【讨论】:
【参考方案5】:当特征数量不多时:
mymap = 'a':1, 'b':2, 'c':3, 'd':4, 'e':5
df.applymap(lambda s: mymap.get(s) if s in mymap else s)
当无法手动操作时:
temp_df2 = pd.DataFrame('data': data.data.unique(), 'data_new':range(len(data.data.unique())))# create a temporary dataframe
data = data.merge(temp_df2, on='data', how='left')# Now merge it by assigning different values to different strings.
【讨论】:
【参考方案6】:您也可以使用 pandas rename_categories
来执行此操作。您首先需要将列定义为 dtype="category"
例如
In [66]: s = pd.Series(["a","b","c","a"], dtype="category")
In [67]: s
Out[67]:
0 a
1 b
2 c
3 a
dtype: category
Categories (3, object): [a, b, c]
然后重命名它们:
In [70]: s.cat.rename_categories([1,2,3])
Out[70]:
0 1
1 2
2 3
3 1
dtype: category
Categories (3, int64): [1, 2, 3]
你也可以传递一个类似dict的对象来映射重命名,例如:
In [72]: s.cat.rename_categories(1: 'x', 2: 'y', 3: 'z')
【讨论】:
一般来说,这个分类类型是干什么用的? @HerrIvan 这里有很多文档pandas.pydata.org/pandas-docs/stable/categorical.html【参考方案7】:我知道这是旧的,但为那些像我一样搜索的人添加。在 pandas 中创建一个数据框,在这段代码中使用 df
ip_addresses = df.source_ip.unique()
ip_dict = dict(zip(ip_addresses, range(len(ip_addresses))))
这将为您提供 IP 地址的字典映射,而无需将其写出来。
【讨论】:
【参考方案8】:DataFrame.replace
呢?
In [9]: mapping = 'set': 1, 'test': 2
In [10]: df.replace('set': mapping, 'tesst': mapping)
Out[10]:
Unnamed: 0 respondent brand engine country aware aware_2 aware_3 age \
0 0 a volvo p swe 1 0 1 23
1 1 b volvo None swe 0 0 1 45
2 2 c bmw p us 0 0 1 56
3 3 d bmw p us 0 1 1 43
4 4 e bmw d germany 1 0 1 34
5 5 f audi d germany 1 0 1 59
6 6 g volvo d swe 1 0 0 65
7 7 h audi d swe 1 0 0 78
8 8 i volvo d us 1 1 1 32
tesst set
0 2 1
1 1 2
2 2 1
3 1 2
4 2 1
5 1 2
6 2 1
7 1 2
8 2 1
正如@Jeff 在 cmets 中指出的那样,在 pandas 版本 .convert_objects() 添加到末尾以正确转换 testst 并设置为 int64
列,以防在后续操作中很重要。
【讨论】:
请注意,您可能希望在替换后执行df.convert_objects()
以强制转换为正确的 dtypes
@Dan Allan 这将是 0.11.1 中的默认设置,仅供参考(转换为对象)
这是超级旧的,但你现在也可以这样做:df.replace(to_replace=['set', 'test'], value=[1, 2])
我认为我们不应该要求硬编码值的名称,它应该在运行时动态提取并分配编号。【参考方案9】:
您可以使用applymap
DataFrame 函数来执行此操作:
In [26]: df = DataFrame("A": [1,2,3,4,5], "B": ['a','b','c','d','e'],
"C": ['b','a','c','c','d'], "D": ['a','c',7,9,2])
In [27]: df
Out[27]:
A B C D
0 1 a b a
1 2 b a c
2 3 c c 7
3 4 d c 9
4 5 e d 2
In [28]: mymap = 'a':1, 'b':2, 'c':3, 'd':4, 'e':5
In [29]: df.applymap(lambda s: mymap.get(s) if s in mymap else s)
Out[29]:
A B C D
0 1 1 2 1
1 2 2 1 3
2 3 3 3 7
3 4 4 3 9
4 5 5 4 2
【讨论】:
我正在解决这样的问题,我只是按照您的答案中提到的确切步骤进行操作。我没有得到输出。 代码: wc = pd.read_csv('PATH', usecols = ['Workclass']) df = pd.DataFrame(wc) 行尾 wcdict = "?":0,"Federal-gov":1,"Local-gov":2 ,"从未工作过":3,"私人":4,"Self-emp-inc":5, "Self-emp-n-inc":6,"State-gov":7,"Without-pay" :8 行尾 df.applymap(lambda s: wcdict.get(s) if s in wcdict else s) 行尾 print(df)df.applymap(lambda s: mymap.get(s) if s in mymap else s)
不会对 df 进行内联更改,因此您的 print df
语句不会反映 applymap 的结果。你需要做一个像df2 = df.applymap(lambda s: mymap.get(s) if s in mymap else s)
这样的分配。 print df2
现在将反映更改。
成功了!!谢谢 :) 我还有一个问题,我需要使用 pyspark 而不是使用普通的 python。这个逻辑的实现在 pyspark 中是否有所不同?当我创建一个数据框时,我给出了文件路径[如上面的 cmets 所示],但是,我想给出一个 RDD 作为数据框的输入。我不能那样做。你对此有什么想法吗?
很高兴它成功了。我真的不确定......也许this 可能是一个开始?以上是关于python pandas用数字替换数据框中的字符串的主要内容,如果未能解决你的问题,请参考以下文章
将 JSON 时间戳字符串转换为 pandas 数据框中的 python 日期
用 pandas 中的 empty_rows 替换 pandas 数据框中的 NaN [重复]