【问题标题】:Delete rows not present in all DataFrame in pandas删除熊猫中所有DataFrame中不存在的行
【发布时间】:2015-10-19 20:46:35
【问题描述】:

背景

有 5 个 DataFrame,我称它们为 b1, b2, b3, b4, b5

它们的数据结构由['Date', 'Value'] 列组成

我得到了 2014 年到 2015 年的数据。

问题

每个 DataFrame 都有不同的日期计数系统。所以,我想去掉 DataFrames 中日期不匹配的行。

我该怎么做?

我尝试过的

所以,如果Date的数据没有包含在所有DataFrame中,我将删除所有数据:b1, b2, b3, b4, b5

这是第一次工作

for i in range(len(b2.index)):
    k = 0
    for j in range(len(b1.index)):
        if b2['Date'][i] == b1['Date'][j]:
            k = k+1
        else:
            k = k
    if k == 1:
        pass
    if k == 0:
        b2 = b2.drop([i])

但是,在那之后我又执行了一次这段代码,会出现这样的错误:

KeyError Traceback(最近一次调用最后一次) 在 () 2k = 0 3for j in range(len(b2.index)): ----> 4 如果 b1['Date'][i] == b2['Date'][j]: 5 k = k+1 6 其他:

C:\Users\cms\Anaconda\lib\site-packages\pandas\core\series.pyc in getitem(self, key) 519def getitem(自我,钥匙): 520尝试: --> 521 结果 = self.index.get_value(self, key) 522 523 如果不是 np.isscalar(结果):

C:\Users\cms\Anaconda\lib\site-packages\pandas\core\index.pyc in get_value(self, series, key) 1593 1594 尝试: -> 1595 返回 self._engine.get_value(s, k) 1596 除了 KeyError 作为 e1: 1597 如果 len(self) > 0 和 self.inferred_type in ['integer','boolean']:

pandas\index.pyx in pandas.index.IndexEngine.get_value (pandas\index.c:3113)()

pandas\index.pyx in pandas.index.IndexEngine.get_value (pandas\index.c:2844)()

pandas\index.pyx in pandas.index.IndexEngine.get_loc (pandas\index.c:3704)()

pandas\hashtable.pyx in pandas.hashtable.Int64HashTable.get_item (pandas\hashtable.c:7224)()

pandas\hashtable.pyx in pandas.hashtable.Int64HashTable.get_item (pandas\hashtable.c:7162)()

密钥错误:28L

我想做的是

mlist = (b1,b2,b3,b4,b5)
for q in mlist:
    for r in mlist:
        for i in range(len(q.index)):
            k = 0
            for j in range(len(r.index)):
                if q['Date'][i] == r['Date'][j]:
                    k = k+1
                else:
                    k = k
            if k == 1:
                pass
            if k == 0:
                q = q.drop([i])`enter code here`

【问题讨论】:

  • q.drop 将索引值作为 arg,不一定是整数索引。试试 q.drop(q.index[i])。另外,不需要k,只需做if q['Date'][i] == r['Date'][j]: continueelse: q = q.drop(q.index[i])

标签: python-2.7 pandas


【解决方案1】:

这个怎么样?使用set.intersecton()

s = set(b1.index)
for b in [b2,b3,b4,b5]:
    s=s.intersection(set(b.index))
for b in [b1,b2,b3,b4,b5]:
    b=b.drop(b.index[-b.index.isin(s)],inplace=True)

【讨论】:

  • 它有点工作,但是,我想让它对每个索引都有相同的索引。例如,b1、b2、b3、b4、b5 需要在索引 #5 中有 2014-07-30,在 #6 中有 2014-07-31。
  • 您能提供示例输入和所需的输出吗?
  • 你能帮帮我吗?如果你给我你的电子邮件或其他东西,我会给你我的数据。实际上,下面的代码运行良好,但是,它返回 'empty' DataFrame,不知道为什么。
  • @SeongNohYoon 为什么不直接写下您尝试此解决方案时出了什么问题,而不是向三个不同的人寻求电子邮件支持?
【解决方案2】:

您希望保留所有数据集中存在的日期。

这可以通过使用the pandas.merge() function 对所有这些对象执行内部连接来轻松完成。

b = b1.merge(on='Date', right=b2, how='inner', suffixes=['', '_b2'])
b = b.merge(on='Date', right=b3, how='inner', suffixes=['', '_b3'])
b = b.merge(on='Date', right=b4, how='inner', suffixes=['', '_b4'])
b = b.merge(on='Date', right=b5, how='inner', suffixes=['_b1', '_b5'])

由于您尚未发布任何示例数据,因此我在这里对您的数据进行了一些假设。

如果我对您的数据有任何错误,请告诉我,我会更正我的示例。

例子:

b1 = pd.DataFrame({'Date':pd.date_range('2015-05-05', '2015-05-10'), 'Value':range(1,7)})
        Date  Value
0 2015-05-05      1
1 2015-05-06      2
2 2015-05-07      3
3 2015-05-08      4
4 2015-05-09      5
5 2015-05-10      6

b2 = pd.DataFrame({'Date':pd.date_range('2015-05-07', '2015-05-12'), 'Value':range(4,10)})
        Date  Value
0 2015-05-05      1
1 2015-05-06      2
2 2015-05-07      3
3 2015-05-08      4
4 2015-05-09      5
5 2015-05-10      6

b = b1.merge(on='Date', right=b2, how='inner', suffixes=['_b1', '_b2'])
        Date  Value_b1  Value_b2
0 2015-05-07         3         4
1 2015-05-08         4         5
2 2015-05-09         5         6
3 2015-05-10         6         7

【讨论】:

  • 你能帮帮我吗?如果你给我你的电子邮件或其他东西,我会给你我的数据。实际上,下面的代码运行良好,但是,它返回 'empty' DataFrame,不知道为什么。
  • @SeongNohYoon 为什么不直接写下您尝试此解决方案时出了什么问题,而不是向三个不同的人寻求电子邮件支持?
  • 首先,join函数中有'right'参数吗?
  • @SeongNohYoon,对不起,我这边的语法错误。它应该是合并功能,而不是连接功能。它现在应该可以工作了。
【解决方案3】:

this posting你可以看到答案

merged_mlist = reduce(lambda left,right: pandas.merge(left,right,on='Date', how='inner'), mlist)

我相信您的代码失败的原因是因为您在删除后没有重置索引。我认为如果您想手动执行此操作,您可以先存储索引,然后一次性删除所有索引

inds_to_drop = []
for i in range(len(b2)):
    for j in range(len(b1)):
        if b2['Date'][i] != b1['Date'][j]:
            inds_to_drop.append(i)
b2.drop( b2.index[inds_to_drop], inplace=True)    
b2.reset_index( drop=True,inplace=True) # this may or may not be necessary, havent thought all the way through

如果你还想实现你的 for 循环,那就更好了

inds_to_drop = [ i for i,dt in enumerate(b2.Date) if not pandas.np.where( b1.Date==dt)[0].size ] 

您可以在每次迭代中都这样做。虽然运行 reduce 函数与 pandas.merge 配对会更容易

【讨论】:

  • 你能帮帮我吗?如果你给我你的电子邮件或其他东西,我会给你我的数据。实际上,下面的代码运行良好,但是,它返回 'empty' DataFrame,不知道为什么。
  • @SeongNohYoon 为什么不直接写下您尝试此解决方案时出了什么问题,而不是向三个不同的人寻求电子邮件支持?
  • 什么是 bad_inds..?
  • 代码的那部分可能有错字。我编辑了它。bad_inds 应该是inds_to_drop.. 但我真的认为你应该尝试第一部分:@987654330 @其中mlist=(b1,b2,b3,b4,b5)
猜你喜欢
  • 2018-07-04
  • 1970-01-01
  • 1970-01-01
  • 2019-03-29
  • 2019-11-08
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 2019-11-24
相关资源
最近更新 更多