【问题标题】:Python pandas: Efficiently compare rows of a dataframe?Python pandas:有效地比较数据帧的行?
【发布时间】:2015-04-29 18:39:15
【问题描述】:

我有数据框'dfm':

match             group  
adamant           86   
adamant           86   
adamant bild      86   
360works          94   
360works          94

如果“组”列相同,我想将“匹配”列的内容两两比较,并将比较结果添加到另一列“结果”中。例如预期的结果是:

   group        compare                              result
    86      adamant, adamant                          same
    86      adamant, adamant bild                   not same
    86      adamant, adamant bild                   not same 
    94      360works,360works                         same

有人可以帮忙吗?

【问题讨论】:

  • 你能清理一下你的预期结果吗?我认为格式没有按您预期的方式出现。不管怎样,这似乎有点令人困惑
  • @benine 对不起!我编辑了文本
  • 你想选择每组中的每一对吗?
  • @James Kelleher 是的,我想比较每组中的所有对
  • 是的,我正要说@DSM

标签: python pandas compare


【解决方案1】:

有点笨拙,但它似乎对我有用:

# initialize the list to store the dictionaries
# that will create the new DataFrame
new_df_dicts = []

# group on 'group'
for group, indices in dfm.groupby('group').groups.iteritems():
    # get the values in the 'match' column
    vals = dfm.ix[indices]['match'].values
    # choose every possible pair from the array of column values
    for i in range(len(vals)):
        for j in range(i+1, len(vals)):
            # compute the new values
            compare = vals[i] + ', ' + vals[j]
            if vals[i] == vals[j]:
                result = 'same'
            else:
                result = 'not same'
            # append the results to the DataFrame
            new_df_dicts.append({'group': group, 'compare': compare, 'result': result})

# create the new DataFrame
new_df = DataFrame(new_df_dicts)

这是我的输出:

                 compare  group    result
0     360works, 360works     94      same
1       adamant, adamant     86      same
2  adamant, adamant bild     86  not same
3  adamant, adamant bild     86  not same

之前我建议将行附加到初始化的 DataFrame。从字典列表中创建一个 DataFrame,而不是对 DataFrame 执行许多附加操作,运行速度大约快 9-10 倍。

【讨论】:

  • kellehr 非常感谢。我收到此错误:TypeError: +: 'float' and 'str' 不支持的操作数类型
  • 当您尝试compare = str(vals[i]) + ', ' + str(vals[j]) 时会发生什么?
  • 那行得通。问题是数据框太大了 193000 行。这个解决方案能更高效吗?
  • 我已经编辑了我的解决方案以使其更快。以前它在您的数据和我的机器上运行大约 0.02 秒。现在,它的运行时间约为 0.003。
【解决方案2】:

这是另一种选择。不确定它是否更有效

import itertools
import pandas as pd

new_df = pd.DataFrame()
for grp in set( dfm['group']):
    for combo in itertools.combinations( dfm[dfm['group'] == grp].index, 2 ):
        # compute the new values
        match1 = dfm['match'][combo[0]]
        match2 = dfm['match'][combo[0]]
        compare = match1 + ', ' + match2
        if match1 == match2:
            result = 'same'
        else:
            result = 'not same'
        # append the results to the DataFrame
        new_df = new_df.append({'group': grp, 'compare': compare, 'result': result}, ignore_index=True)

print new_df

(格式是从詹姆斯的回答中借用的)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 2017-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-21
    相关资源
    最近更新 更多