【发布时间】:2021-09-13 23:09:26
【问题描述】:
我的样本数据如下:
# df
VAR1 SEQ VAR2 VAR3 DATE VAR4 VAR5 VAR6 VAR7
AAA 1 YYY 01 20000630 AL 11111 ABCD PA
BBB 1 YYY 01 20100701 GA 12345 EDED NY
BBB 2 YYY 01 20150815 GA 12345 NY
BBB 3 YYY 01 19950105 GA 12345 YTRU NY
BBB 4 YYY 01 20000701 GA 12345 IIII NY
BBB 5 YYY 01 20210701 GA 12345 NY
CCC 1 NNN 01 20210630 CA 33333 SSSS NJ
CCC 2 NNN 01 20210629 CA 33333 NJ
在SAS中,我们可以导出固定宽度的格式文件如下:
BLANK_VAR1 = " "
%MACRO FRIST;
PUT @ 1 "00FIRST"
@ 8 VAR1 $CHAR5.
@ 13 BLANK_VAR1 $CHAR2.
@ 15 VAR2 $CHAR3.
;
%MEND FRIST;
%MACRO SECOND;
PUT @ 1 "00SECOND"
@ 9 VAR3 $CHAR2.
@ 11 BLANK_VAR1 $CHAR2.
@ 13 VAR4 $CHAR2.
@ 15 VAR5 $CHAR5.
;
%MEND SECOND;
%MACRO THIRD(sequence);
num = &sequence.;
PUT @ 1 num Z2.0
@ 3 "THIRD" $CHAR5.
@ 8 DATE $CHAR8.
;
%MEND THIRD;
%MACRO FOURTH(sequence);
num = &sequence.;
PUT @ 1 num Z2.0
@ 3 "FOURTH" $CHAR5.
@ 9 VAR6 $CHAR25.
@ 34 BLANK_VAR1 $CHAR2.
@ 36 VAR7 $CHAR2.
;
%MEND FOURTH;
filename outtmp "/home/folder/outfile_tmp";
DATA _NULL_;
SET df;
BY VAR1 SEQ;
FILE outtmp;
IF FIRST.VAR1 THEN DO;
%FRIST;
%SECOND;
REC_CNT = 0;
END;
REC_CNT + 1;
IF REC_CNT LE 3 THEN DO;
%THIRD(REC_CNT);
IF VAR6 NE ' ' THEN DO;
%FOURTH(COUNTN);
END;
END;
RUN;
filename output "/home/folder/output";
%MACRO INREC;
PUT 001 RECIN $CHAR150.;
%MEND INREC;
%MACRO FILE_FIRST;
DATE = TODAY();
PUT @ 1 "###FIRSTLINE###"
@ 16 DATE JULIAN5.
@ 21 BLANK_VAR1 $CHAR2.
@ 23 "###FIRSTLINEEND###"
;
%MEND FILE_FIRST;
%MACRO FILE_LAST;
DATE = TODAY();
PUT @ 1 "###LASTLINE###"
@ 15 DATE JULIAN5.
@ 20 BLANK_VAR1 $CHAR2.
@ 22 "###LASTLINEEND###"
;
%MEND FILE_LAST;
DATA output;
INFILE outtmp truncover;
INPUT
@ 001 RECIN $CHAR150.;
RUN;
DATA _NULL_;
SET output end=last;
file output lrecl=256 ;
IF _N_ = 1 THEN DO;
%FILE_FIRST;
END;
%INREC;
IF last THEN DO;
%FILE_LAST;
END;
RUN;
###FIRSTLINE###21182 ###LASTLINEEND###
00FIRSTAAA YYY
00SECOND01 AL11111
01THIRD20000630
01FOURTHABCD PA
00FIRSTBBB YYY
00SECOND01 GA12345
01THIRD20100701
01FOURTHEDED NY
02THIRD20150815
03THIRD19950105
03FOURTHYTRU NY
00FIRSTCCC NNN
00SECOND01 CA33333
01THIRD20210630
01FOURTHSSSS NJ
###LASTLINE###21182 ###LASTLINEEND###
上述程序的逻辑是:
- 需要输出四个部分。
- 如果有多个相同的
VAR1,则只输出FIRST和SECOND一次。 -
SEQ的输出THIRD部分小于3。如果SEQ大于3,则不输出。忽略。 - 在第三个逻辑之后输出
FOURTH部分,并且如果VAR6没有丢失。 - 注意:在
THIRD和FOURTH部分中,前两个字符串应从01更改为03,具体取决于记录。
如何在Python 中复制这种格式?
我发现np.savetxt() 和fmt 参数可能是link 的一种方式;但是,该文件应与原始数据帧的顺序相同。
pandas 具有read_fwf() 读取固定宽度格式文件的功能;但是,没有要导出的 to_fwf() 函数。
我已经卡了好几天了,所以任何想法都应该有帮助!
【问题讨论】:
-
我想你只要把整行变成一个字符串,然后写那个?
-
@Joe 第一行和最后一行可以通过这个来完成,但如果你有一个大数据集,中间部分就很难做到。
-
明确地说,您只是希望您的数据以固定宽度或其他方式导出?我无法从您发布的输出中看出?
-
@PeterChen 我的意思是,这在 SAS 中也很困难,但是......这基本上就是你正在做的即使在 SAS 中 - 你正在将记录转换为字符串(在文本文件),然后将它们读回并再次写出。 (在 SAS 中执行此操作可能比您正在执行的操作要容易得多,老实说,但把它放在一边……)老实说,这里更大的问题只是说明您遵循的规则 - 不清楚规则是什么,当然超出程序指令。如果前三行有值,你写 First Second 一次,Third 三次,Fourth 写?
-
@JonSG 固定格式是他在 SAS 中所做的,至少。但它更像是被分割成一堆行,有点像旧的“卡片列”格式,但也不完全是……我认为它一定是银行系统的东西,因为没有其他东西会这样奇怪。
标签: python pandas numpy text sas