我最近迁移到Python作为我的主要分析工具,我希望能够复制第一个。 &安培;持续。 SAS中的功能。 SAS代码如下:
data data.out;
set data.in;
if first.ID then flag = 1;
if last.ID then flag = 1;
run;
输出如下;
ID flag
AAAA 1
AAAA 0
AAAA 0
AAAA 1
BBBB 1
BBBB 0
BBBB 0
BBBB 1
CCCC 1
CCCC 0
CCCC 1
有关如何在Python中执行此操作的任何想法?
答案 0 :(得分:4)
如果您正在使用python和处理数字,那么通常会使用pandas
完成此类事情:
pip install pandas
假设您有CSV文件,则可以使用pd.read_csv
加载数据。我不会对您的输入做出假设,因此请查看文档。加载数据框后,即可继续。
import pandas
df = pd.read_csv('file.csv')
df
ID
0 AAAA
1 AAAA
2 AAAA
3 AAAA
4 BBBB
5 BBBB
6 BBBB
7 BBBB
8 CCCC
9 CCCC
10 CCCC
df['flag'] = ((df.ID != df.ID.shift()) | (df.ID != df.ID.shift(-1))).astype(int)
df
ID flag
0 AAAA 1
1 AAAA 0
2 AAAA 0
3 AAAA 1
4 BBBB 1
5 BBBB 0
6 BBBB 0
7 BBBB 1
8 CCCC 1
9 CCCC 0
10 CCCC 1
你也可以使用np.where
(Brad Solomon的赞赏建议)来做到这一点:
df['flag'] = np.where((df.ID != df.ID.shift()) \
| (df.ID != df.ID.shift(-1)), 1, 0)
df
ID flag
0 AAAA 1
1 AAAA 0
2 AAAA 0
3 AAAA 1
4 BBBB 1
5 BBBB 0
6 BBBB 0
7 BBBB 1
8 CCCC 1
9 CCCC 0
10 CCCC 1
答案 1 :(得分:3)
使用pandas:
import pandas as pd
import numpy as np
df = pd.DataFrame(['AAAA', 'AAAA', 'AAAA', 'AAAA',
'BBBB', 'BBBB', 'BBBB', 'BBBB', 'CCCC', 'CCCC', 'CCCC',],
columns=['ID'])
def firstlast(a):
# For each character grouping set, create a 1d array of 0s padded
# with 1s, equal to length of the group.
a = np.zeros(len(a)-2)
a = np.pad(a, (1,1), 'constant', constant_values=(1,1))
return a
df['flag'] = (s.groupby(s).apply(firstlast).apply(pd.Series).stack()
.astype(int).values)
print(df)
ID flag
0 AAAA 1
1 AAAA 0
2 AAAA 0
3 AAAA 1
4 BBBB 1
5 BBBB 0
6 BBBB 0
7 BBBB 1
8 CCCC 1
9 CCCC 0
10 CCCC 1
从逻辑上@cᴏʟᴅsᴘᴇᴇᴅ窃取一点(比上述解决方案更聪明),但使用numpy.where
:
ids = df.ID
df['flag'] = np.where((ids!=ids.shift(1)) | (ids!=ids.shift(-1)), 1, 0)
print(df)
ID flag
0 AAAA 1
1 AAAA 0
2 AAAA 0
3 AAAA 1
4 BBBB 1
5 BBBB 0
6 BBBB 0
7 BBBB 1
8 CCCC 1
9 CCCC 0
10 CCCC 1
答案 2 :(得分:2)
我觉得这自然是一个groupby概念,理想情况下会使用基于groupby的方法,尽管基于班次的方法肯定没有任何问题(请参阅下面的简要讨论以获取更多信息):
df.loc[ df.groupby('ID',as_index=False).nth([0,-1]).index, 'flag' ] = 1
nth(0)
选择每个groupby的第一行,nth(-1)
选择nth([0,-1])
选择两者。这将使其他行丢失,可以使用fillna(0)
轻松填充。
df.flag = df.flag.fillna(0).astype(int)
ID flag
0 AAAA 1
1 AAAA 0
2 AAAA 0
3 AAAA 1
4 BBBB 1
5 BBBB 0
6 BBBB 0
7 BBBB 1
8 CCCC 1
9 CCCC 0
10 CCCC 1
关于@JonClements的评论,请注意使用groupby会导致对排序顺序的答案不变,而使用shift方法将取决于排序顺序(根据具体情况,其中任何一种都可能是首选)。 / p>
答案 3 :(得分:1)
对不起,晚会。原始要求的变化。如何使用python程序捕获sas第一个点记录?以下示例基于https://pandas.pydata.org/pandas-docs/stable/getting_started/comparison/comparison_with_sas.html
首先进行sas设置: sample_dot_last和sample_dot_first数据集是我需要python生成的数据!
data sampledata;
infile cards4;
input ( x y ) ( 2*$8. ) z record_number;
cards;
A I 10 1
A I 11 2
A I 11 3
A J 15 4
B K 9 5
B K 10 6
B K 10 7
B L 14 8
C I 7 9
C I 19 10
C K 3 11
C K 5 12
;;;;
proc print data= sampledata;
run;
data sample_dot_last;
set sampledata;
by x y z;
if last.y;
run;
proc print data= sample_dot_last;
run;
data sample_dot_first;
set sampledata;
by x y z;
if first.y;
run;
proc print data= sample_dot_first;
run;
Python的第二个csv示例:
x,y,z,record number
A,I,10,1
A,I,11,2
A,I,11,3
A,J,15,4
B,K,9,5
B,K,10,6
B,K,10,7
B,L,14,8
C,I,7,9
C,I,19,10
C,K,3,11
C,K,5,12
最后是python程序,请注意dataframe.groupby([...]).last()或.first() 产生与sas完全相同的输出!
import numpy as np
import pandas as pd
import os
cwd= os.getcwd()
print( "cwd={}".format( cwd ))
df1= pd.read_csv( 'sampledata.csv')
print( df1 )
df2= df1.groupby( [ 'x', 'y' ]).last()
print( df2 )
df3= df1.groupby( [ 'x', 'y' ]).first()
print( df3 )
很抱歉,不同的问题和答案,希望对您有用。