Pandas错误尝试将字符串转换为整数

3

需求:

数据框中的某一列是“混合”类型。它可以具有类似于 "123456" 或者 "ABC12345" 的值。

使用 xlsxwriter 将此数据框写入 Excel 文件中。

对于像 "123456" 这样的值,Pandas 将其转换为 123456.0(使其看起来像浮点数)。

如果值完全是数字,则需要将其作为 +整数(即 123456)放入 xlsx 中。

努力:

以下是代码片段

import pandas as pd
import numpy as np
import xlsxwriter
import os
import datetime
import sys
excel_name = str(input("Please Enter Spreadsheet Name :\n").strip())

print("excel entered :   "   , excel_name)
df_header = ['DisplayName','StoreLanguage','Territory','WorkType','EntryType','TitleInternalAlias',
         'TitleDisplayUnlimited','LocalizationType','LicenseType','LicenseRightsDescription',
         'FormatProfile','Start','End','PriceType','PriceValue','SRP','Description',
         'OtherTerms','OtherInstructions','ContentID','ProductID','EncodeID','AvailID',
         'Metadata', 'AltID', 'SuppressionLiftDate','SpecialPreOrderFulfillDate','ReleaseYear','ReleaseHistoryOriginal','ReleaseHistoryPhysicalHV',
          'ExceptionFlag','RatingSystem','RatingValue','RatingReason','RentalDuration','WatchDuration','CaptionIncluded','CaptionExemption','Any','ContractID',
          'ServiceProvider','TotalRunTime','HoldbackLanguage','HoldbackExclusionLanguage']
first_pass_drop_duplicate = df_m_d.drop_duplicates(['StoreLanguage','Territory','TitleInternalAlias','LocalizationType','LicenseType',
                                   'LicenseRightsDescription','FormatProfile','Start','End','PriceType','PriceValue','ContentID','ProductID',
                                   'AltID','ReleaseHistoryPhysicalHV','RatingSystem','RatingValue','CaptionIncluded'], keep=False) 
# We need to keep integer AltID  as is

first_pass_drop_duplicate.loc[first_pass_drop_duplicate['AltID']] =   first_pass_drop_duplicate['AltID'].apply(lambda x : str(int(x)) if str(x).isdigit() == True else x)

我已经尝试过:

1. using `dataframe.astype(int).astype(str)` # works as long as value is not alphanumeric
2.importing re and using pure python `re.compile()` and `replace()` -- does not work
3.reading DF row by row in a for loop !!! Kills the machine as dataframe can have 300k+ records

每次,我都会得到一个错误:
raise KeyError('%s不在索引中' % objarr[mask])
KeyError: '[102711. 102711. 102711. 102711. 102711. 102711. 102711. 102711.
102711. 102711. 102711. 102711. 102711. 102711. 102711. 102711.
102711. 102711. 102711. 102711. 102711. 102711. 102711. 102711.
102711. 102711. 102711. 102711. 102711. 102711. 102711. 102711.
102711. 102711. 102711. 102711. 102711. 102711. 102711. 102711.
102711. 102711. 102711. 102711. 102711. 102711. 102711. 102711.
102711. 102711. 102711. 102711. 102711. 102711. 102711. 102711.
5337. 5337. 5337. 5337. 5337. 5337. 5337. 5337.
5337. 5337. 5337. 5337. 5337. 5337. 5337. 5337.
5337. 5337. 5337. 5337. 5337. 5337. 5337. 5337.
5337. 5337. 5337. 5337. 5337. 5337. 5337. 5337.
5337. 5337. 5337. 5337. 5337. 5337. 5337. 5337.
5337. 5337. 2124. 2124. 2124. 2124. 2124. 2124.
2124. 2124. 6643. 6643. 6643. 6643. 6643. 6643.
6643. 6643. 6643. 6643. 6643. 6643. 6643. 6643.
6643. 6643. 6643. 6643. 6643. 6643. 6643. 6643.]不在索引中'

我是Python / Pandas的新手,非常感谢任何帮助和解决方案。


所以你只需要将数字值转换为 float,而非数字则不需要转换是吗? - jezrael
我需要确保它将a +整数视为文本/字符串,而不是在末尾添加.0(小数点),这实际上会显示在Excel中。 - SanBan
所以你需要将所有的值转换为“字符串”类型?问题是“Excel”解析将转换为“字符串”的“int”值作为“浮点数”? - jezrael
在Pandas中,AltID中的任何值都应被视为字符串。 - SanBan
嗯,先尝试转换为 string 类型:first_pass_drop_duplicate.ix[first_pass_drop_duplicate.AltI‌​D.astype(str).str.isdigit(), 'AltID'] = pd.to_numeric(first_pass_drop_duplicate.AltID, errors='coerce') - jezrael
显示剩余3条评论
3个回答

2

我认为你需要使用to_numeric函数:

df = pd.DataFrame({'AltID':['123456','ABC12345','123456'],
                   'B':[4,5,6]})

print (df)
      AltID  B
0    123456  4
1  ABC12345  5
2    123456  6

df.ix[df.AltID.str.isdigit(), 'AltID']  = pd.to_numeric(df.AltID, errors='coerce')

print (df)
      AltID  B
0    123456  4
1  ABC12345  5
2    123456  6

print (df['AltID'].apply(type))
0    <class 'float'>
1      <class 'str'>
2    <class 'float'>
Name: AltID, dtype: object

太棒了!对于我的系列来说,它没有起作用,因为第四个元素已经是一个 intpd.Series([1], dtype=object).str.isdigit() 返回 NaN。我不得不这样做:s.ix[s.str.isdigit().fillna(False)] = pd.to_numeric(s, errors='coerce'),然后它就完美地工作了。 - piRSquared
而且!这几乎肯定更快。 - piRSquared
@piRSquared - 谢谢。另一个解决方案是 df.ix[df.AltID.astype(str).str.isdigit(), 'AltID'] = pd.to_numeric(df.AltID, errors='coerce') - jezrael

1
使用参数为errors='ignore'applypd.to_numeric方法。 考虑pd.Series s
s = pd.Series(['12345', 'abc12', '456', '65hg', 54, '12-31-2001'])

s.apply(pd.to_numeric, errors='ignore')

0         12345
1         abc12
2           456
3          65hg
4            54
5    12-31-2001
dtype: object

注意类型。
s.apply(pd.to_numeric, errors='ignore').apply(type)

0    <type 'numpy.int64'>
1            <type 'str'>
2    <type 'numpy.int64'>
3            <type 'str'>
4            <type 'int'>
5            <type 'str'>
dtype: object

1
最后,通过在pandas read_excel格式中使用“转换器”选项,它成功了。
df_w02 = pd.read_excel(excel_name, names = df_header,converters = {'AltID':str,'RatingReason' : str}).fillna("")

转换器可以将类型“转换”为由我的函数/值定义,并将整数存储为字符串而不添加小数点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接