Python / pandas n00b。我有处理存储在csv文件中的事件数据的代码。来自df["CONTACT PHONE NUMBER"]
的数据输出的电话号码为“5555551212.0”显然,“。0”是一个问题,但是因为它是一个整数,我想是吗?
Anyhoo,我决定为了可用性而格式化电话号码。
该号码来自csv文件,未格式化。该数字将始终为十位数:5555551212,但我想将其显示为(555)555-1212。
import glob
import os
import pandas as pd
import sys
csvfiles = os.path.join(directory, '*.csv')
for csvfile in glob.glob(csvfiles):
df = pd.read_csv(filename)
#formatting the contact phone
phone_nos = df["CONTACT PHONE NUMBER"]
for phone_no in phone_nos:
contactphone = "(%c%c%c)%c%c%c-%c%c%c%c" % tuple(map(ord,phone_no))
最后一行给出了以下错误:
not enough arguments for format string
但也许这不是熊猫这样做的方式。由于我正在迭代一个数组,我还需要将数据保存在现有列中,或者在处理完电话号码后重建该列。
答案 0 :(得分:4)
我认为电话号码should be stored as a string 读取csv时,可以确保将该列读取为字符串:
pd.read_csv(filename, dtype={"CONTACT PHONE NUMBER": str})
您可以使用字符串方法,天真地添加:
In [11]: s = pd.Series(['5554443333', '1114445555', np.nan, '123']) # df["CONTACT PHONE NUMBER"]
# phone_nos = '(' + s.str[:3] + ')' + s.str[3:7] + '-' + s.str[7:11]
编辑:在相关问题中为Noah answers,您可以使用str.replace更直接/更有效地执行此操作:
In [12]: phone_nos = s.str.replace('^(\d{3})(\d{3})(\d{4})$', r'(\1)\2-\3')
In [13]: phone_nos
Out[13]:
0 (555)4443-333
1 (111)4445-555
2 NaN
3 123
dtype: object
但是这里有一个问题,因为你的数字格式不正确,而不是10位数,所以你可以NaN那些:
In [14]: s.str.contains('^\d{10}$') # note: NaN is truthy
Out[14]:
0 True
1 True
2 NaN
3 False
dtype: object
In [15]: phone_nos.where(s.str.contains('^\d{10}$'))
Out[15]:
0 (555)4443-333
1 (111)4445-555
2 NaN
3 NaN
dtype: object
现在,您可能希望检查自己的错误格式(也许您必须更改输出以包含它们,例如,如果它们包含国家/地区代码):
In [16]: s[~s.str.contains('^\d{10}$').astype(bool)]
Out[16]:
3 123
dtype: object
答案 1 :(得分:3)
我认为问题是电话号码存储为float64
,因此,添加一些内容将修复您的内部循环:
In [75]:
df['Phone_no']
Out[75]:
0 5554443333
1 1114445555
Name: Phone_no, dtype: float64
In [76]:
for phone_no in df['Phone_no']:
contactphone = "(%c%c%c)%c%c%c-%c%c%c%c" % tuple(map(ord,list(str(phone_no)[:10])))
print contactphone
(555)444-3333
(111)444-5555
但是,我认为将电话号码设为string
更容易(@Andy_Hayden对缺失的值做了一个很好的观点,所以我编写了以下数据集:)
In [121]:
print df
Phone_no Name
0 5554443333 John
1 1114445555 Jane
2 NaN Betty
[3 rows x 2 columns]
In [122]:
df.dtypes
Out[122]:
Phone_no float64
Name object
dtype: object
#In [123]: You don't need to convert the entire DataFrame, only the 'Phone_no' needs to be converted.
#
#df=df.astype('S4')
In [124]:
df['PhoneNumber']=df['Phone_no'].astype(str).apply(lambda x: '('+x[:3]+')'+x[3:6]+'-'+x[6:10])
In [125]:
print df
Phone_no Name PhoneNumber
0 5554443333.0 John (555)444-3333
1 1114445555.0 Jane (111)444-5555
2 NaN Betty (nan)-
[3 rows x 3 columns]
In [134]:
import numpy as np
df['PhoneNumber']=df['Phone_no'].astype(str).apply(lambda x: np.where((len(x)>=10)&set(list(x)).issubset(list('.0123456789')),
'('+x[:3]+')'+x[3:6]+'-'+x[6:10],
'Phone number not in record'))
In [135]:
print df
Phone_no Name PhoneNumber
0 5554443333 John (555)444-3333
1 1114445555 Jane (111)444-5555
2 NaN Betty Phone number not in record
[3 rows x 3 columns]
答案 2 :(得分:2)
您可以使用库 clean_phone()
中的函数 DataPrep。使用 pip install dataprep
安装。
>>> from dataprep.clean import clean_phone
>>> df = pd.DataFrame({'phone': [5555551212, '5555551212']})
>>> clean_phone(df, 'phone', output_format='national')
Phone Number Cleaning Report:
2 values cleaned (100.0%)
Result contains 2 (100.0%) values in the correct format and 0 null values (0.0%)
phone phone_clean
0 5555551212 (555) 555-1212
1 5555551212 (555) 555-1212