Python 指定csv中每列的长度(填充)
我正在尝试重新安排一个文件以匹配BACS银行格式。为了使其工作,csv中的列需要具有特定的长度。我已经计算出了abcdbao列,因为它是一个重复模式(文件中还有几列),但有几列有随机数,我无法轻松确定 有没有一种方法可以让我(理想情况下)根据标题将某个特定列作为目标,或者将所有内容(最多一个逗号)作为目标,从而破坏一些可以工作的内容? 在下面的示例文件中,您将看到值更改的三列。如果将所有内容都定位到一个特定的字符是解决方案,那么我考虑使用.l将列填充到指定的长度(然后在excel中手动排序) 原始文件Python 指定csv中每列的长度(填充),python,python-3.x,csv,Python,Python 3.x,Csv,我正在尝试重新安排一个文件以匹配BACS银行格式。为了使其工作,csv中的列需要具有特定的长度。我已经计算出了abcdbao列,因为它是一个重复模式(文件中还有几列),但有几列有随机数,我无法轻松确定 有没有一种方法可以让我(理想情况下)根据标题将某个特定列作为目标,或者将所有内容(最多一个逗号)作为目标,从而破坏一些可以工作的内容? 在下面的示例文件中,您将看到值更改的三列。如果将所有内容都定位到一个特定的字符是解决方案,那么我考虑使用.l将列填充到指定的长度(然后在excel中手动排序) 原
a,b,c,d,e,f,g,h,i,j,k
12345,1234567,0,11,123456,12345678,1234567,abcdabcd,A ABCD
123456,12345678,0,11,123456,12345678,12345678,abcdabcd,A ABCD
123456,1234567,0,11,123456,12345678,12345,abcdabcd,A ABCD
12345,1234567,0,11,123456,12345678,1234567,abcdabcd,A ABCD
123456,12345678,0,11,123456,12345678,123456789,abcdabcd,A ABCD
with open('file.txt', 'r') as file :
filedata = file.read()
filedata = filedata.replace('12345', '12345'.ljust(6, '0'))
with open('file.txt', 'w') as file:
file.write(filedata)
理想输出
a,b,c,d,e,f,g,h,i,j,k
123450,12345670,0,11,123456,12345678,123456700,abcdabcd,A ABCD
123456,12345678,0,11,123456,12345678,123456780,abcdabcd,A ABCD
123456,12345670,0,11,123456,12345678,123450000,abcdabcd,A ABCD
123450,12345670,0,11,123456,12345678,123456700,abcdabcd,A ABCD
123456,12345678,0,11,123456,12345678,123456789,abcdabcd,A ABCD
代码
a,b,c,d,e,f,g,h,i,j,k
12345,1234567,0,11,123456,12345678,1234567,abcdabcd,A ABCD
123456,12345678,0,11,123456,12345678,12345678,abcdabcd,A ABCD
123456,1234567,0,11,123456,12345678,12345,abcdabcd,A ABCD
12345,1234567,0,11,123456,12345678,1234567,abcdabcd,A ABCD
123456,12345678,0,11,123456,12345678,123456789,abcdabcd,A ABCD
with open('file.txt', 'r') as file :
filedata = file.read()
filedata = filedata.replace('12345', '12345'.ljust(6, '0'))
with open('file.txt', 'w') as file:
file.write(filedata)
编辑:
类似于此,但不是针对每个标题的特定列,就是至少针对第一列
编辑2:
我正在使用下面的命令重新排列我的列,是否可以修改它以处理字符串长度
import pandas as pd
## Read csv / tab-delimited in this example
df = pd.read_csv('test.txt', sep='\t')
## Reorder columns
df = df[['h','i','c','g','a','b','e','d','f','j','k']]
## Write csv / tab-delimited
df.to_csv('test', sep='\t')
使用pandas,可以将列转换为
str
,然后使用.str.pad
。您可以按要求的长度制作dict:
lengths = {
"a": 6,
"b": 8,
"c": 3,
"d": 6,
"e": 8,
}
然后像这样使用它:
result = pd.DataFrame(
{
column_name: column.str.pad(
lengths.get(column_name, 0), side="right", fillchar="0"
)
for column_name, column in df.astype(str).items()
}
)
如果每列的
fillchar
不同,您也可以使用pandas从dict中获取它,您可以将该列转换为str
,然后使用.str.pad
。您可以按要求的长度制作dict:
lengths = {
"a": 6,
"b": 8,
"c": 3,
"d": 6,
"e": 8,
}
>>> print '{:0>5}'.format(4)
'00004'
>>> print '{:0<5}'.format(4)
'40000'
>>> print '{:0^5}'.format(4)
'00400'
然后像这样使用它:
result = pd.DataFrame(
{
column_name: column.str.pad(
lengths.get(column_name, 0), side="right", fillchar="0"
)
for column_name, column in df.astype(str).items()
}
)
如果每列的fillchar
不同,您也可以从dict中获得它>打印“{:0>5}”。格式(4)
>>> print '{:0>5}'.format(4)
'00004'
>>> print '{:0<5}'.format(4)
'40000'
>>> print '{:0^5}'.format(4)
'00400'
'00004'
>>>打印“{:0>>>打印“{:0>5}”。格式(4)
'00004'
>>>print'{:0成功地到达了那里,所以我想我会发表文章,以防有人有类似的问题。这只适用于一个专栏,但现在对我来说已经足够了
#import pandas
import pandas as pd
#open file and convert data to str
data = pd.read_csv('Test.CSV', dtype = str)
# width of output string
width = 6
# fillchar
char ="_"
#Change the contents of column named ColumnID
data["ColumnID"]= data["ColumnID"].str.ljust(width, char)
#print output
print(data)
我设法做到了这一点,所以我想如果有人有类似的问题,我会发帖子。这只适用于一个专栏,但现在对我来说已经足够了
#import pandas
import pandas as pd
#open file and convert data to str
data = pd.read_csv('Test.CSV', dtype = str)
# width of output string
width = 6
# fillchar
char ="_"
#Change the contents of column named ColumnID
data["ColumnID"]= data["ColumnID"].str.ljust(width, char)
#print output
print(data)
你只是想填充一个列来匹配最长的项目吗?你可以遍历行并保留最长匹配项的索引,然后再次迭代填充。嗨,Simon,不,文件本身有一个特定的顺序,新列从字符1、7、15、18、24、32等开始。我在这里试图做的是确保检查的第一列ple总是6个字符长,因此从char 7开始的第2列包含正确的信息。在我的csv中有超过1k行,因此手动执行此操作将花费永远的时间,但如果我可以针对第一列并确保其中的字符长度正确,我可以找到一种方法来实现此功能。csv文件就是用单词分隔的行y逗号。“列”基本上是行上某个索引处的所有字段。除非原始文件的格式不同(您在问题中没有描述),否则最简单的方法是逐行迭代。您还可以使用熊猫之类的工具来操作csv(maarten的答案)。这很有意义。该文件的格式与我的示例中的格式类似,只是由逗号分隔的文本行和数字行,在字符串的特定点包含相同的信息。您是否只是尝试填充一列以匹配最长的项?您可以迭代行并保留最长匹配项的索引,然后再次迭代以填充。您好Simon,不,文件本身有一个特定的顺序,新的列从字符1、7、15、18、24、32开始,等等。我在这里要做的是确保第一列的长度始终为6个字符,因此从字符7开始的第2列中包含正确的信息。在我的csv中有超过1k行,因此手动这样做会花费很长时间,但是如果我能以第一列为目标,并确保其中的字符长度正确,我就能找到一种方法来实现这一点。csv文件只是用逗号分隔的单词行。“列”基本上是行上某个索引处的所有字段。除非原始文件的格式不同(你的问题中没有描述),最简单的方法是逐行迭代。你也可以使用pandas之类的工具来操作csv(maarten的答案)。这很有意义。该文件的格式与我的示例中的格式相同,只是由逗号分隔的文本行和数字行,在字符串的特定点上包含相同的信息。这很好,但我的问题是数字不一样(在我的示例中应该更清楚),否则我会用filedata.replace和.rjust处理它们。我能在字符串索引中指定a、b、c、d作为1、2、3和第4项吗?这就是我基本上想要的(我认为)。这很好,但我的问题是数字不一样(在我的示例中应该更清楚),否则我会用filedata.replace和.rjust处理它们。我能在字符串索引中指定a、b、c、d作为1、2、3和第4项吗?这就是我基本上想要的(我想)。我想这是最接近我想要的。我不确定如何准确地实现它(我目前正在使用pandas移动专栏,希望不会有太大的不同)。感谢你把我推向正确的方向,Maarten。我认为这是最接近我所追求的。我不知道如何准确地实现它(我目前正在使用pandas移动专栏,希望不会有太大的不同).谢谢你把我推向正确的方向Maarten。