获取数据框中缺失的行
Posted
技术标签:
【中文标题】获取数据框中缺失的行【英文标题】:Get missing rows in dataframe 【发布时间】:2021-10-22 00:30:53 【问题描述】:我有一个这样的数据框:
Object Period
A 202101
A 202102
A 202103
A 202105
A 202107
B 202102
B 202103
B 202104
B 202106
现在我想对每个对象进行迭代并获取对象的最小值和最大值之间的缺失时间段,并得到如下内容:
Object MissingValues
A 202104 / 202106
B 202105
为了使问题更简单,最小对象为 202101,最大对象为 202108。
我对如何做到这一点有点迷茫。 你能帮助我吗? 谢谢
【问题讨论】:
请以文本而非图像的形式提供示例数据。 【参考方案1】:您可以通过dt.to_period()
将Period
字符串转换为Pandas 句点。然后按Object
分组并聚合以获取每组Object
的缺失时段。最后,将缺失周期列表转换为所需的布局,如下:
df['Period'] = pd.to_datetime(df['Period'], format='%Y%m').dt.to_period('M')
df_out = df.groupby('Object')['Period'].agg(lambda x: sorted(list(set(pd.period_range(x.min(), x.max()).tolist()) - set(x))))
df_out = df_out.apply(lambda x: ' / '.join(map(str, x))).str.replace('-', '').reset_index()
结果:
print(df_out)
Object Period
0 A 202104 / 202106
1 B 202105
编辑
如果您希望将 Period
的最终布局作为字符串列表,例如['202104','202106'] 代替 '202104' / '202106',你可以使用:
df['Period'] = pd.to_datetime(df['Period'], format='%Y%m').dt.to_period('M')
df_out = df.groupby('Object')['Period'].agg(lambda x: sorted(list(set(pd.period_range(x.min(), x.max()).tolist()) - set(x))))
df_out = df_out.apply(lambda x: [str(y).replace('-', '') for y in x]).reset_index()
结果:
print(df_out)
Object Period
0 A [202104, 202106]
1 B [202105]
【讨论】:
最好处理跨年的日期范围。我更喜欢这个解决方案。 @ScottBoston 谢谢!你的解决方案也不错! :-) 非常感谢斯科特。最后,我最好把它放在一个列表中 ['202104','202106'] 而不是 '202104' / '202106'。你知道我应该做些什么不同的事情吗?我试过这个但不起作用: def f(x): listi = [] x = x.astype(int) s = pd.Series(np.arange(x.min(), x.max()+1 )) r = s[~s.isin(x)] return listi.append(r.astype(str)) @ImFabien75 请参阅我上面的编辑以将其设置在列表 ['202104','202106'] 而不是 '202104' / '202106' 中。 Scott 更喜欢我的解决方案,并且已经删除了他的解决方案。 谢谢@SeaBean。我得到一个错误的想法:TypeError:传递 PeriodDtype 数据无效。改用data.to_timestamp()
我想期间转换不起作用:/【参考方案2】:
import pandas as pd
data = 'Object':['A', 'A','A', 'A','A','B','B','B','B'],
'Period':[202101,202102,202103,202105,202107,202102,202103,202104,202106]
outputDf = pd.DataFrame(data)
uniqueObject=outputDf.Object.unique()
grouped = outputDf.groupby('Object')
outputDf = pd.DataFrame(columns = ['Object', 'Period'])
for object in uniqueObject:
periodValues=[]
for periodValue in grouped.get_group(object)['Period']:
periodValues.append(periodValue)
mini=min(periodValues)
maxi=max(periodValues)
periodStr=""
for i in range(mini,maxi+1):
if i not in periodValues:
periodStr+=str(i)+' / '
periodStr = periodStr[:-2]
outputDf = outputDf.append('Object' : object, 'Period' : periodStr,
ignore_index = True)
print(outputDf.to_string(index=False))
【讨论】:
以上是关于获取数据框中缺失的行的主要内容,如果未能解决你的问题,请参考以下文章