首页 > 解决方案 > 如何以最少的列值从其他数据框中唯一地定义一个数据框?

问题描述

我是 Python 和数据框架的新手,并试图解决机器学习问题,但遇到了问题。我真的需要找到解决这个问题的方法。

我有 3 个二进制值数据帧。每个15*40

遍历每个数据帧,我需要找到每一行的最小列数,这可以从其他数据帧的其他行中唯一地定义该数据帧的那一行。

如果是数据帧的一行,可以根据其他数据帧的最小可能列数来唯一标识。我将在该数据框中查找类似的列值并将其删除。(生成规则)

这样,我相信可以找到可以从其他数据框中定义该数据框条目的最小列数及其值。

有没有什么简单的方法可以在 Python 或 pandas 中做到这一点?

我被卡住了,但到目前为止还没有成功。

例子:

数据框1:

1 0 1 0
0 1 1 0
1 0 1 1

数据框2:

1 1 1 0
1 1 1 0
1 1 1 1

数据框 3:

0 0 1 0
0 0 1 0
1 1 0 1

预期的输出是这样的:

2 唯一定义数据框 1 的规则:

2 唯一定义数据框 2 的规则:

2 唯一定义数据框 3 的规则:

这就是我想根据列值定义规则以唯一标识具有最少列数的数据框的方式。

我试图遵循的伪代码:

  1. 对于数据框中的每一行i
  2. 计算其他数据框中每列值的出现次数
  3. 根据它们的出现值对第i行中的所有列进行排序
  4. 查找有序列列表中的最小列数,将第i行与其他数据框中的其他行唯一区分开来
  5. 删除该数据框中也满足找到的列及其值的所有行。

如果该数据帧的长度不为0,则继续,

是否有任何库或简单的方法可以做到这一点?

标签: pythonpandasdataframe

解决方案


我以这种方式解决了这个特殊问题。这是一个可行的解决方案。rules它最后打印一个数组rules,每个数据帧包含一个数组。该数组由一个字典组成,说明{columnName: columnValue}

import pandas as pd
import itertools

df0 = pd.DataFrame([[1, 0, 1, 0], [0, 1, 1, 0], [1, 0, 1, 1]])
df1 = pd.DataFrame([[1, 1, 1, 0], [1, 1, 1, 0], [1, 1, 1, 1]])
df2 = pd.DataFrame([[0, 0, 1, 0], [0, 0, 1, 0], [1, 1, 0, 1]])

print(df0)
print(df1)
print(df2)

list_dfs = [df0, df1, df2]


def find_rules(list_dfs):
    rules_sets = []
    for idx, df in enumerate(list_dfs):
        trgt_df = df
        other_df = [x for i, x in enumerate(list_dfs) if i != idx]
        other_df = pd.concat(other_df, ignore_index=True)

        def count_occur(value, col_name):
            return other_df[col_name].value_counts().get(value, 0)

        df_dict = []

        for idx, row in trgt_df.iterrows():
            listz = {}
            for col_name in list(trgt_df.columns):
                listz[col_name] = [row[col_name],
                                   count_occur(row[col_name], col_name)]
            df_dict.append(sorted(listz.items(), key=lambda x: x[1][1]))

        rules = []

        def check_for_uniquness(list_of_attr):
            for row in other_df.itertuples(index=False):
                conditions = len(list_of_attr)
                for atr in list_of_attr:
                    if row[atr[0]] == atr[1][0]:
                        conditions = conditions-1
                if conditions == 0:
                    return False
            return True

        def find_col_val(row, val):
            for r in row:
                if r[0] == val:
                    return r[1][0]

        def mark_similar(df_cur, list_of_attr):
            new = []
            for idx, row in enumerate(df_cur):
                combinations = len(list_of_attr)
                for atr in list_of_attr:
                    if find_col_val(row, atr[0]) == atr[1][0]:
                        combinations = combinations-1
                if combinations == 0:
                    new.append(idx)
            return [x for i, x in enumerate(df_cur) if i not in new]

        def return_dictionary(list_of_attr):
            dic = {}
            for idx, el in enumerate(list_of_attr):
                dic[el[0]] = el[1][0]
            return dic

        def possible_combinations(stuff):
            lists = []
            for L in range(0, len(stuff)+1):
                for subset in itertools.combinations(stuff, L):
                    lists.append(list(subset))
            del lists[0]
            return lists

        def X2R(df_dict):
            for elm in df_dict:
                combinations = possible_combinations(list(range(0, len(elm))))
                for combin in combinations:
                    column_combinations = []
                    for i in combin:
                        column_combinations.append(elm[i])
                    if check_for_uniquness(column_combinations):
                        rules.append(return_dictionary(
                            column_combinations))
                        return mark_similar(df_dict, column_combinations)

        while len(df_dict):
            df_dict = X2R(df_dict)

        rules_sets.append(rules)
    return rules_sets


rules = find_rules(list_dfs)
print(rules)

推荐阅读