[英]replace strings in every column with numbers
这个问题是这个问题的延伸。 考虑下表中可视化的 pandas DataFrame。
受访者 | 牌 | 引擎 | 国家 | 知道的 | 意识到_2 | 意识到_3 | 年龄 | 测试 | 放 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 一个 | 沃尔沃 | p | 瑞典 | 1 | 0 | 1 | 23 | 放 | 放 |
1 | b | 沃尔沃 | 没有任何 | 瑞典 | 0 | 0 | 1 | 45 | 放 | 放 |
2 | c | 宝马 | p | 我们 | 0 | 0 | 1 | 56 | 测试 | 测试 |
3 | d | 宝马 | p | 我们 | 0 | 1 | 1 | 43 | 测试 | 测试 |
4 | e | 宝马 | d | 德国 | 1 | 0 | 1 | 34 | 放 | 放 |
5 | F | 奥迪 | d | 德国 | 1 | 0 | 1 | 59 | 放 | 放 |
6 | G | 沃尔沃 | d | 瑞典 | 1 | 0 | 0 | 65 | 测试 | 放 |
7 | H | 奥迪 | d | 瑞典 | 1 | 0 | 0 | 78 | 测试 | 放 |
8 | 一世 | 沃尔沃 | d | 我们 | 1 | 1 | 1 | 32 | 放 | 放 |
要转换包含字符串条目的列,应该先执行 map ,然后pandas.replace()
。
例如:
mapping = {'set': 1, 'test': 2}
df.replace({'set': mapping, 'tesst': mapping})
这将导致以下 DataFrame(表):
受访者 | 牌 | 引擎 | 国家 | 知道的 | 意识到_2 | 意识到_3 | 年龄 | 测试 | 放 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 一个 | 沃尔沃 | p | 瑞典 | 1 | 0 | 1 | 23 | 1 | 1 |
1 | b | 沃尔沃 | 没有任何 | 瑞典 | 0 | 0 | 1 | 45 | 1 | 1 |
2 | c | 宝马 | p | 我们 | 0 | 0 | 1 | 56 | 2 | 2 |
3 | d | 宝马 | p | 我们 | 0 | 1 | 1 | 43 | 2 | 2 |
4 | e | 宝马 | d | 德国 | 1 | 0 | 1 | 34 | 1 | 1 |
5 | F | 奥迪 | d | 德国 | 1 | 0 | 1 | 59 | 1 | 1 |
6 | G | 沃尔沃 | d | 瑞典 | 1 | 0 | 0 | 65 | 2 | 1 |
7 | H | 奥迪 | d | 瑞典 | 1 | 0 | 0 | 78 | 2 | 1 |
8 | 一世 | 沃尔沃 | d | 我们 | 1 | 1 | 1 | 32 | 1 | 1 |
如上所示,最后两列的字符串被替换为代表这些字符串的数字。
那么问题来了:是否有一种更快且不那么动手的方法来将所有字符串替换为一个数字? 可以自动创建一个映射(以及 output 它在某个地方供人类参考)吗?
使 DataFrame 最终变成这样的东西:
受访者 | 牌 | 引擎 | 国家 | 知道的 | 意识到_2 | 意识到_3 | 年龄 | 测试 | 放 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 23 | 1 | 1 |
1 | 2 | 1 | 2 | 1 | 0 | 0 | 1 | 45 | 1 | 1 |
2 | 3 | 2 | 1 | 2 | 0 | 0 | 1 | 56 | 2 | 2 |
3 | 4 | 2 | 1 | 2 | 0 | 1 | 1 | 43 | 2 | 2 |
4 | 5 | 2 | 3 | 3 | 1 | 0 | 1 | 34 | 1 | 1 |
5 | 6 | 3 | 3 | 3 | 1 | 0 | 1 | 59 | 1 | 1 |
6 | 7 | 1 | 3 | 1 | 1 | 0 | 0 | 65 | 2 | 1 |
7 | 8 | 3 | 3 | 1 | 1 | 0 | 0 | 78 | 2 | 1 |
8 | 9 | 1 | 3 | 2 | 1 | 1 | 1 | 32 | 1 | 1 |
还有 output:
[{'volvo': 1, 'bmw': 2, 'audi': 3}, {'p': 1, 'None': 2, 'd': 3}, {'swe': 1, 'us': 2, 'germany': 3}]
请注意,地图(字典)的 output 列表不应硬编码,而是由代码生成。
您可以调整此响应https://stackoverflow.com/a/39989896/15320403中给出的代码(在您链接的帖子中)为您选择的每一列生成映射并按照您的建议应用替换
all_brands = df.brand.unique()
brand_dic = dict(zip(all_brands, range(len(all_brands))))
您需要首先将列的类型更改为Categorical
,然后创建一个新列或使用codes
覆盖现有列:
df['brand'] = pd.Categorical(df['brand'])
df['brand_codes'] = df['brand'].cat.codes
如果您需要映射:
dict(enumerate(df['brand'].cat.categories )) #This will work only after you've converted the column to categorical
从其他答案中,我写了这个 function 来解决这个问题:
import pandas as pd
def convertStringColumnsToNum(data):
columns = data.columns
columns_dtypes = data.dtypes
maps = []
for col_idx in range(0, len(columns)):
# don't change columns already comprising of numbers
if(columns_dtypes[col_idx] == 'int64'): # can be extended to more dtypes
continue
# inspired from Shivam Roy's answer
col = columns[col_idx]
tmp = pd.Categorical(data[col])
data[col] = tmp.codes
maps.append(tmp.categories)
return maps
此 function 返回用于将字符串替换为数字代码的maps
。 代码是字符串驻留在列表中的索引。 这个 function 有效,但它带有SettingWithCopyWarning
。
如果它没有坏就不要修理它,对吧? ;)
*但如果有人有办法调整此 function 以便不再显示警告,请随时发表评论。 然而它有效*耸耸肩* *
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.