如何将数据集中的字符串列转换为 int?
How can I convert columns of string in dataset to int?
数据集中的一些数据是字符串格式,我应该将它们全部映射到数字形式。我想将数据集中某些列中的字符串数据转换为 int int,以便在 knn 方法中可用。我写了这段代码,但它有这个错误。我该如何解决?
感谢您的考虑。
此错误出现在这部分代码中:
def string_to_int(s):
ord3 = lambda x : '%.3d' % ord(x)
return int(''.join(map(ord3, s)))
for i in range(1,24857):
df.iloc[i,0]=string_to_int(df.iloc[i,0])
df.iloc[i,1]=string_to_int(df.iloc[i,1])
df.iloc[i,3]=string_to_int(df.iloc[i,3])
df.iloc[i,8]=string_to_int(df.iloc[i,8])
df.iloc[i,9]=string_to_int(df.iloc[i,9])
df.iloc[i,10]=string_to_int(df.iloc[i,10])
df.iloc[i,11]=string_to_int(df.iloc[i,11])
df.iloc[i,12]=string_to_int(df.iloc[i,12])
错误是:
TypeError Traceback (most recent call last)
<ipython-input-7-f5bce11c577a> in <module>()
30 df.iloc[i,10]=string_to_int(df.iloc[i,10])
31 df.iloc[i,11]=string_to_int(df.iloc[i,11])
---> 32 df.iloc[i,12]=string_to_int(df.iloc[i,12])
33
34
<ipython-input-7-f5bce11c577a> in string_to_int(s)
20 def string_to_int(s):
21 ord3 = lambda x : '%.3d' % ord(x)
---> 22 return int(''.join(map(ord3, s)))
23
24 for i in range(1, 24857):
TypeError: 'float' object is not iterable
总代码在这里:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
!pip install sklearn
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import classification_report, confusion_matrix
#-----------------read file-------------------
uploaded = files.upload()
with open('dataset.csv', 'r') as data:
df3 = pd.read_csv(data , encoding = ('ansi'))
lst = ['id', 'Prold', 'ProCreationId', 'CustCreatonRate', 'TaskCreationTimestamp', 'Price', 'ServiceId', 'CategoryId', 'ZoneId', 'TaskState', 'TargetProId', 'isFraud']
df = pd.DataFrame(df3)
print (df)
#----------------------preprocessing----------------
def string_to_int(s):
ord3 = lambda x : '%.3d' % ord(x)
return int(''.join(map(ord3, s)))
for i in range(1,24857):
df.iloc[i,0]=string_to_int(df.iloc[i,0])
df.iloc[i,1]=string_to_int(df.iloc[i,1])
df.iloc[i,3]=string_to_int(df.iloc[i,3])
df.iloc[i,8]=string_to_int(df.iloc[i,8])
df.iloc[i,9]=string_to_int(df.iloc[i,9])
df.iloc[i,10]=string_to_int(df.iloc[i,10])
df.iloc[i,11]=string_to_int(df.iloc[i,11])
df.iloc[i,12]=string_to_int(df.iloc[i,12])
这是因为您在数据集中的第 12 列 (TargetProId) 具有 NaN 值(它是数据框中的空值)。
所以你需要用其他字符串替换它。
例如,您可以将 na 值替换为“Unknown”。
df["TargetProId"]=df["TargetProId"].fillna("Unknown")
NaN
值来自原始 csv 文件中的空字符串。要将它们保留为空字符串,您可以使用 df = pd.read_csv(url, keep_default_na=False)
读取 csv,尽管将它们设为 NaN
可以更容易地处理它们。
然而,如评论中所述,我对该数据中使用的编码标准(如果有)的正确解释持怀疑态度。
但是如果问题中描述的是这样,那么您可以使用您的函数 string_to_int
而不做任何更改,将其应用于所有 '...Id'
列并跳过 NaN
(并且可以选择将它们转换为另一个值):
id_cols = [k for k in df.columns if k.lower().endswith('id')]
df2 = df.copy()
df2[id_cols] = df2[id_cols].applymap(string_to_int, na_action='ignore')
# optional: convert nan to some int value (here: 0)
df2[id_cols] = df2[id_cols].fillna(0)
结果
>>> df2['TargetProId'].head()
0 1181130851071200850681170691090660551030720870...
1 8911811810612110611210908812010605205108207407...
2 0
3 0
4 0
Name: TargetProId, dtype: object
(注意:dtype 仍然是 object
因为 int 值溢出 int64
,而是 Python 的任意精度 int 对象;df2.applymap(type).value_counts()
显示所有 'id'
列都是 <class 'int'>
).
原建议
最初我对 string_to_int()
有另一个建议。它使用默认值显式处理非 str 值。它还使用 struct.unpack()
作为更高性能解码的基础,尽管在这种特定情况下,我怀疑它有多大区别。
import struct
def string_to_int2(s, default=0):
if isinstance(s, str):
n = len(s)
b = s.encode('ascii')
return int(''.join([f'{v:03d}' for v in struct.unpack(f'{n}B', b)]))
return default
df2 = df.copy()
df2[id_cols] = df2[id_cols].applymap(string_to_int2)
数据集中的一些数据是字符串格式,我应该将它们全部映射到数字形式。我想将数据集中某些列中的字符串数据转换为 int int,以便在 knn 方法中可用。我写了这段代码,但它有这个错误。我该如何解决? 感谢您的考虑。
此错误出现在这部分代码中:
def string_to_int(s):
ord3 = lambda x : '%.3d' % ord(x)
return int(''.join(map(ord3, s)))
for i in range(1,24857):
df.iloc[i,0]=string_to_int(df.iloc[i,0])
df.iloc[i,1]=string_to_int(df.iloc[i,1])
df.iloc[i,3]=string_to_int(df.iloc[i,3])
df.iloc[i,8]=string_to_int(df.iloc[i,8])
df.iloc[i,9]=string_to_int(df.iloc[i,9])
df.iloc[i,10]=string_to_int(df.iloc[i,10])
df.iloc[i,11]=string_to_int(df.iloc[i,11])
df.iloc[i,12]=string_to_int(df.iloc[i,12])
错误是:
TypeError Traceback (most recent call last)
<ipython-input-7-f5bce11c577a> in <module>()
30 df.iloc[i,10]=string_to_int(df.iloc[i,10])
31 df.iloc[i,11]=string_to_int(df.iloc[i,11])
---> 32 df.iloc[i,12]=string_to_int(df.iloc[i,12])
33
34
<ipython-input-7-f5bce11c577a> in string_to_int(s)
20 def string_to_int(s):
21 ord3 = lambda x : '%.3d' % ord(x)
---> 22 return int(''.join(map(ord3, s)))
23
24 for i in range(1, 24857):
TypeError: 'float' object is not iterable
总代码在这里:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from google.colab import files
!pip install sklearn
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import classification_report, confusion_matrix
#-----------------read file-------------------
uploaded = files.upload()
with open('dataset.csv', 'r') as data:
df3 = pd.read_csv(data , encoding = ('ansi'))
lst = ['id', 'Prold', 'ProCreationId', 'CustCreatonRate', 'TaskCreationTimestamp', 'Price', 'ServiceId', 'CategoryId', 'ZoneId', 'TaskState', 'TargetProId', 'isFraud']
df = pd.DataFrame(df3)
print (df)
#----------------------preprocessing----------------
def string_to_int(s):
ord3 = lambda x : '%.3d' % ord(x)
return int(''.join(map(ord3, s)))
for i in range(1,24857):
df.iloc[i,0]=string_to_int(df.iloc[i,0])
df.iloc[i,1]=string_to_int(df.iloc[i,1])
df.iloc[i,3]=string_to_int(df.iloc[i,3])
df.iloc[i,8]=string_to_int(df.iloc[i,8])
df.iloc[i,9]=string_to_int(df.iloc[i,9])
df.iloc[i,10]=string_to_int(df.iloc[i,10])
df.iloc[i,11]=string_to_int(df.iloc[i,11])
df.iloc[i,12]=string_to_int(df.iloc[i,12])
这是因为您在数据集中的第 12 列 (TargetProId) 具有 NaN 值(它是数据框中的空值)。 所以你需要用其他字符串替换它。 例如,您可以将 na 值替换为“Unknown”。
df["TargetProId"]=df["TargetProId"].fillna("Unknown")
NaN
值来自原始 csv 文件中的空字符串。要将它们保留为空字符串,您可以使用 df = pd.read_csv(url, keep_default_na=False)
读取 csv,尽管将它们设为 NaN
可以更容易地处理它们。
然而,如评论中所述,我对该数据中使用的编码标准(如果有)的正确解释持怀疑态度。
但是如果问题中描述的是这样,那么您可以使用您的函数 string_to_int
而不做任何更改,将其应用于所有 '...Id'
列并跳过 NaN
(并且可以选择将它们转换为另一个值):
id_cols = [k for k in df.columns if k.lower().endswith('id')]
df2 = df.copy()
df2[id_cols] = df2[id_cols].applymap(string_to_int, na_action='ignore')
# optional: convert nan to some int value (here: 0)
df2[id_cols] = df2[id_cols].fillna(0)
结果
>>> df2['TargetProId'].head()
0 1181130851071200850681170691090660551030720870...
1 8911811810612110611210908812010605205108207407...
2 0
3 0
4 0
Name: TargetProId, dtype: object
(注意:dtype 仍然是 object
因为 int 值溢出 int64
,而是 Python 的任意精度 int 对象;df2.applymap(type).value_counts()
显示所有 'id'
列都是 <class 'int'>
).
原建议
最初我对 string_to_int()
有另一个建议。它使用默认值显式处理非 str 值。它还使用 struct.unpack()
作为更高性能解码的基础,尽管在这种特定情况下,我怀疑它有多大区别。
import struct
def string_to_int2(s, default=0):
if isinstance(s, str):
n = len(s)
b = s.encode('ascii')
return int(''.join([f'{v:03d}' for v in struct.unpack(f'{n}B', b)]))
return default
df2 = df.copy()
df2[id_cols] = df2[id_cols].applymap(string_to_int2)