熊猫中分类变量的顺序

时间:2019-10-11 01:00:19

标签: python pandas

我有一个看起来像这样的Pandas数据框:

Input DataFrame

其中a, b, c, d是分类变量,例如a < b < c < db > 3 * ac > 2 * bd > 1.5 * c。如果给出了这些显式关系,则如何将行与其他所有隐式关系(例如c > 6 * ad > 9 * ad > 3 * b等)添加到此数据框。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

假设您有一个如下所示的数据框(我添加了列名以提高可读性)

df
  Cat1 Cat2  Relationship
0    a    b           3.0
1    b    c           2.0
2    c    d           1.5

首先在前两列上合并df本身,然后通过将合并后的行上的原始2个关系值相乘来计算新的关系值。重复相同的操作,直到达到所有关系为止。

import pandas as pd
df = pd.DataFrame(data=[['a', 'b', 3],
                        ['b', 'c', 2],
                        ['c', 'd', 1.5]],
                  columns=['Cat1', 'Cat2', 'Relationship'])
max_length_of_relationships = len(df)
for i in range(max_length_of_relationships):
    df2 = df.merge(df, left_on='Cat2', right_on='Cat1')
    df2['Relationship'] = df2['Relationship_x'] * df2['Relationship_y']
    df2 = df2[['Cat1_x', 'Cat2_y', 'Relationship']]
    df2.columns = ['Cat1', 'Cat2', 'Relationship']
    df = df.append(df2).drop_duplicates()

产生

df
  Cat1 Cat2  Relationship
0    a    b           3.0
1    b    c           2.0
2    c    d           1.5
0    a    c           6.0
1    b    d           3.0
1    a    d           9.0

这里的棘手问题是我假设max_length_of_relationships是数据帧的行数,这实际上是最坏的情况。如果max_length_of_relationships较小时数据帧较大,则性能会很差。在这种情况下,您可能需要使用@Quang建议的networkx来找到图形中的最长路径。

代码示例

import networkx as nx
G=nx.from_pandas_edgelist(df, 'Cat1', 'Cat2', edge_attr=True, create_using=nx.DiGraph())
print(nx.dag_longest_path(G))
max_length_of_relationships = nx.dag_longest_path_length(G)

答案 1 :(得分:1)

如所评论,这是一个图形问题:

df = pd.DataFrame({'0': {0: 'a', 1: 'b', 2: 'c'},
 '1': {0: 'b', 1: 'c', 2: 'd'},
 '2': {0: 3.0, 1: 2.0, 2: 1.5}})

# as we multiplying, we convert the values to log
df[2] = np.log(df[2].astype(float)).astype(float)

# create the graphs
G = nx.DiGraph()

# add the edges
G.add_weighted_edges_from([(x,y,w) for 
                               x,y,w in zip(df[0],df[1],df[2])])

# compute all the path:
np.exp(pd.concat([pd.DataFrame(y, index=[x]) for x,y in
            nx.all_pairs_dijkstra_path_length(G)],
          sort=False)
         .replace(0, np.nan)
         .stack()

      )

输出:

a  b    3.0
   c    6.0
   d    9.0
b  c    2.0
   d    3.0
c  d    1.5
dtype: float64