我正在尝试确定哪些连续行在一列中至少有50个重复项。然后我想能够以总结的方式读取哪些行有重复,即
start end total
9 60 51
200 260 60
我试着把开始和结束分开,这样我以后就可以独立地拜访他们了。我用这个打开.csv文件并读取其内容:
df = pd.read_csv("BN4 A4-F4, H4_row1_column1_watershed_label.csv", header=None)
df.groupby(0).filter(lambda x: len(x) > 0)
这给了我这个:
0
0 52.0
1 65.0
2 52.0
3 52.0
4 52.0
... ...
4995 8.0
4996 8.0
4997 8.0
4998 8.0
4999 8.0
5000 rows × 1 columns
我对此有很多问题。1( 我不确定我是否完全理解第二个函数。它似乎应该把我专栏中的数字组合在一起。此代码:
df.groupby(0).count()
给我这个:
0
0.0
1.0
2.0
3.0
4.0
...
68.0
69.0
70.0
71.0
73.0
65 rows × 0 columns
我认为这意味着在我的专栏中总共有65个不同的独特身份。这并不能告诉我它们是什么或在哪里。我以为这就是的作用
df.groupby(0).filter(lambda x: len(x) > 0)
但如果我将0更改为其他任何内容,那么它就会破坏我生成的列表。
问题2(我想,为了获得序列中重复项的数量以及它们在哪行,我可能需要使用for循环,但我不确定如何构建它。到目前为止,我已经花了一整天的时间试图弄清楚它,但我只是觉得我对Python还不够了解。
我能得到一些帮助吗?
更新
谢谢!这就是我对@piterbarg:的感谢
#function to identify which behaviors have at least 49 frames, and give the starting, ending, and number of frames
def behavior():
df2 = (df
.reset_index()
.shift(periods=-1)
.groupby((df[0].diff() != 0).cumsum()) #if the diff between a row and the prev row is not 0, increase cumulative sum
.agg({0 : 'mean', 'index':['first','last',len]})) #mean is the behavior category
df3 = (df2.where(df2[('index','len')]>49)
.dropna() #drop N/A
.astype(int) #type = int
.reset_index(drop = True))
print(df3)
out:
0 index
mean first last len
0 7 32 87 56
1 19 277 333 57
2 1 785 940 156
3 30 4062 4125 64
4 29 4214 4269 56
5 7 4450 4599 150
6 1 4612 4775 164
7 7 4778 4882 105
8 8 4945 4999 56
当前的问题是试图使数据帧包括我的.csv的最后一行。如果有人碰巧看到这个,我会喜欢你的输入!
让我们从嘲笑df:开始
import numpy as np
np.random.seed(314)
df=pd.DataFrame({0:np.random.randint(10,size = 5000)})
# make sure we have a couple of large blocks
df.loc[300:400,0] = 5
df.loc[600:660,0] = 4
首先,我们确定了连续数字的变化发生在哪里,以及每个这样的组的groupby
。我们记录它从哪里开始,从哪里结束,以及每组的大小
df2 = (df.reset_index()
.groupby((df[0].diff() != 0).cumsum())
.agg({'index':['first','last',len]})
)
然后我们只选择那些超过50 的组
(df2.where(df2[('index','len')]>50)
.dropna()
.astype(int)
.reset_index(drop = True)
)
输出:
index
first last len
0 300 400 101
1 600 660 61
对于你关于df.groupby(0).filter(lambda x: len(x) > 0)
做什么的问题,据我所知,它什么都没做。它按列0中的不同值进行分组,然后丢弃那些大小为0的组,根据定义,这些组都不是。因此,这将返回您的完整df
编辑
你的代码不太正确,应该是
def behavior():
df2 = (df.reset_index()
.groupby((df[0].diff() != 0).cumsum())
.agg({0 : 'mean', 'index':['first','last',len]}))
df3 = (df2.where(df2[('index','len')]>50)
.dropna()
.astype(int)
.reset_index(drop = True))
print(df3)
注意,我们定义并返回df3
而不是df2,我还修改了代码以返回在mean
列中重复的值(很抱歉,名称不是很直观,但如果您愿意,可以更改它们(
first
是重复开始时的索引,last
是最后一个索引,而len
是有多少元素。
#function to identify which behaviors have at least 49 frames, and give the starting, ending, and number of frames
def behavior():
df2 = (df.reset_index()
.groupby((df[0].diff() != 0).cumsum()) #if the diff between a row and the prev row is not 0, increase cumulative sum
.agg({0 : 'mean', 'index':['first','last',len]})) #mean is the behavior category
.shift(-1)
df3 = (df2.where(df2[('index','len')]>49)
.dropna() #drop N/A
.astype(int) #type = int
.reset_index(drop = True))
print(df3)
得出以下结果:
0 index
mean first last len
0 7 31 86 56
1 19 276 332 57
2 1 784 939 156
3 31 4061 4124 64
4 29 4213 4268 56
5 8 4449 4598 150
6 1 4611 4774 164
7 8 4777 4881 105
8 8 4944 4999 56
我喜欢。我确实注意到,有56x个"7"副本的组实际上从第32行开始,到第87行结束(在这两种情况下都只晚了一行,整个表格的模式是一致的(。我相信用shift((函数可以以某种方式解决这个问题,这是对的吗?我还在玩这个:D