获取数据框中缺失的行

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))

【讨论】:

以上是关于获取数据框中缺失的行的主要内容,如果未能解决你的问题,请参考以下文章

如何根据数据框中的列值获取特定的行数[重复]

在不计算的情况下获取 Spark 数据框中的行数

如何使用另一个日期时间索引获取具有日期时间索引的 Pandas 数据框中的行?

如何获取熊猫数据框中的行,列中具有最大值并保留原始索引?

如何使用过滤器从scala中的数据框中获取包含空值的行集

Python,Pandas:只返回那些有缺失值的行