如何用唯一ID替换Python Pandas表文本值?

时间:2016-08-14 19:31:28

标签: python python-3.x pandas

我正在使用Pandas以这种格式读取文件:

fp = pandas.read_table("Measurements.txt")
fp.head()

"Aaron", 3, 5, 7  
"Aaron", 3, 6, 9  
"Aaron", 3, 6, 10 
"Brave", 4, 6, 0 
"Brave", 3, 6, 1

我想用唯一ID替换每个名称,因此输出如下:

"1", 3, 5, 7 
"1", 3, 6, 9 
"1", 3, 6, 10 
"2", 4, 6, 0 
"2", 3, 6, 1

我该怎么做?

谢谢!

4 个答案:

答案 0 :(得分:5)

我会使用categorical dtype:

In [97]: x['ID'] = x.name.astype('category').cat.rename_categories(range(1, x.name.nunique()+1))

In [98]: x
Out[98]:
    name  v1  v2  v3 ID
0  Aaron   3   5   7  1
1  Aaron   3   6   9  1
2  Aaron   3   6  10  1
3  Brave   4   6   0  2
4  Brave   3   6   1  2

如果您需要字符串ID而不是数字ID,您可以使用:

x.name.astype('category').cat.rename_categories([str(x) for x in range(1,x.name.nunique()+1)])

或正如@MedAli在his answer中提到的,使用factorize()方法 - 演示:

In [141]: x['cat'] = pd.Categorical((pd.factorize(x.name)[0] + 1).astype(str))

In [142]: x
Out[142]:
    name  v1  v2  v3 ID cat
0  Aaron   3   5   7  1   1
1  Aaron   3   6   9  1   1
2  Aaron   3   6  10  1   1
3  Brave   4   6   0  2   2
4  Brave   3   6   1  2   2

In [143]: x.dtypes
Out[143]:
name      object
v1         int64
v2         int64
v3         int64
ID      category
cat     category
dtype: object

In [144]: x['cat'].cat.categories
Out[144]: Index(['1', '2'], dtype='object')

或将类别作为整数:

In [154]: x['cat'] = pd.Categorical((pd.factorize(x.name)[0] + 1))

In [155]: x
Out[155]:
    name  v1  v2  v3 ID cat
0  Aaron   3   5   7  1   1
1  Aaron   3   6   9  1   1
2  Aaron   3   6  10  1   1
3  Brave   4   6   0  2   2
4  Brave   3   6   1  2   2

In [156]: x['cat'].cat.categories
Out[156]: Int64Index([1, 2], dtype='int64')

说明:

In [99]: x.name.astype('category')
Out[99]:
0    Aaron
1    Aaron
2    Aaron
3    Brave
4    Brave
Name: name, dtype: category
Categories (2, object): [Aaron, Brave]

In [100]: x.name.astype('category').cat.categories
Out[100]: Index(['Aaron', 'Brave'], dtype='object')

In [101]: x.name.astype('category').cat.rename_categories([1,2])
Out[101]:
0    1
1    1
2    1
3    2
4    2
dtype: category
Categories (2, int64): [1, 2]

factorize()方法的解释:

In [157]: (pd.factorize(x.name)[0] + 1)
Out[157]: array([1, 1, 1, 2, 2])

In [158]: pd.Categorical((pd.factorize(x.name)[0] + 1))
Out[158]:
[1, 1, 1, 2, 2]
Categories (2, int64): [1, 2]

答案 1 :(得分:4)

您可以通过简单的字典映射来实现。 比如说您的数据如下所示:

col1, col2, col3, col4
"Aaron", 3, 5, 7  
"Aaron", 3, 6, 9  
"Aaron", 3, 6, 10 
"Brave", 4, 6, 0 
"Brave", 3, 6, 1

然后简单地做

myDict = {"Aaron":"1", "Brave":"2"}
fp["col1"] = fp["col1"].map(myDict)

如果您不想构建字典,请使用pandas.factorize,它将从0开始为您编写列。您可以找到有关如何使用它的示例{{3 }}。

答案 2 :(得分:0)

为什么不在名称上使用哈希

df["col0"] = df["col0"].apply(lambda x: hashlib.sha256(x.encode("utf-8")).hexdigest())

通过这种方式,您无需关心发生的名称,即您不需要事先了解它们来构建用于映射的字典。

答案 3 :(得分:0)

看起来这Replace all occurrences of a string in a pandas dataframe可能会得到你的回答。根据文档,pandas.read_table创建了一个数据框,数据框具有替换功能。

fp.replace({'Aaron': '1'}, regex=True)

虽然您可能不需要使用正则表达式= True部分,因为它可以完全直接替换。