【问题标题】:Dataframe concat concrete value Rows of two dataframes数据框 concat 具体值 两个数据框的行
【发布时间】:2021-04-30 11:57:49
【问题描述】:

我需要再次重组我的数据。 我有两个数据框:df1 和 df2,我想要 df3

    df1      df2         df3
   1 2 3      1 2 3     a 1 b 4 c 7 
 1 a b c    1 1 2 3     d 1 e 4 f 7 
 2 d e f    2 4 5 6     g 1 h 4 i 7
 3 g h i    3 7 8 9     a 2 b 5 c 8
                        d 2 e 5 f 8
                        g 2 h 5 i 8
                        a 3 b 6 c 9
                        d 3 e 6 f 9
                        g 3 h 6 i 9 

所以df3的逻辑应该类似于矩阵乘法。 我确实尝试修改并回答了我昨天的问题:

    a,b = df.shape
m = int(a/2)
x = pd.DataFrame(df.iloc[:m,np.r_[m:b]].to_numpy()).T
y = pd.DataFrame(df.iloc[m:,:m].to_numpy())

out = (pd.concat((y,x),axis=1).sort_index(axis=1)
         .set_axis(df.columns,axis=1,inplace=False))
                             

我确实成功地实现了这段代码,但是我自己的修改并没有得到我想要的结果。 欢迎和赞赏任何推荐。请考虑以下信息:

  1. 3x3 是示例性的,因此给定的数据框形状可能因大小和形状而异
  2. 两个给定的数据框将始终具有相同的形状和大小
  3. 昨天的问题 -> 好答案 -> 错误的问题,我的坏问题 Reorganize elements of Pandas Dataframe by row and column to new dataframe
  4. 我知道有一种方法可以从 pandas 中的矩阵乘法自动获取结果矩阵。我已经在我的脚本中实现并使用了它。
  5. 在 df1 中仅使用数字而在 df2 中仅使用字母是为了更容易理解尝试做什么。 换句话说,所需的数据结构可以描述为:

我希望这篇大文章可以澄清我的问题。由于我是新来的,我也感谢批评我寻求帮助并改善我在 Stack-Overflow 上的沟通方式。

一个小更新: 我发现这个Pandas concatenate alternating columns Thread 非常接近我想要做的事情。因为我必须在几分钟内工作,所以我不能试一试。 但是对于所有想为我的问题做出贡献的人来说,这可能会更容易并提供一些灵感。

我明天会继续努力,让你们更新。

提前致以诚挚的问候和感谢,

汉斯·彼得

【问题讨论】:

    标签: python python-3.x pandas dataframe matrix


    【解决方案1】:

    设法得到这个,使用itertools

    prod = itertools.product(df2.T.values, df1.values)
    pd.DataFrame.from_records(itertools.chain.from_iterable(zip(lets, nums)) for nums, lets in prod)
    # output
       0  1  2  3  4  5
    0  a  1  b  4  c  7
    1  d  1  e  4  f  7
    2  g  1  h  4  i  7
    3  a  2  b  5  c  8
    4  d  2  e  5  f  8
    5  g  2  h  5  i  8
    6  a  3  b  6  c  9
    7  d  3  e  6  f  9
    8  g  3  h  6  i  9
    

    解释:我取df1.valuesdf2的转置,并使用itertools.product()(我在这里使用了tolist(),以便更清晰;但它实际上会产生 np 数组。) 产生这个:

    list(itertools.product(df2.T.values.tolist(), df1.values.tolist()))
    [([1, 4, 7], ['a', 'b', 'c']),
     ([1, 4, 7], ['d', 'e', 'f']),
     ([1, 4, 7], ['g', 'h', 'i']),
     ([2, 5, 8], ['a', 'b', 'c']),
     ([2, 5, 8], ['d', 'e', 'f']),
     ([2, 5, 8], ['g', 'h', 'i']),
     ([3, 6, 9], ['a', 'b', 'c']),
     ([3, 6, 9], ['d', 'e', 'f']),
     ([3, 6, 9], ['g', 'h', 'i'])]
    

    我先使用数字 (df2),然后使用字母 (df1),以便产品的顺序符合您的要求。否则第一列将是 3 个 a、3 个 d 和 3 个 g - 但您实际上是 3 个 1、3 个 2 和 3 个 3。

    zip'ing 这将为我提供每个字母和数字的元组列表。

    for nums, lets in prod:
        print(list(zip(lets, nums)))  # letters before numbers
    # output:
    [('a', 1), ('b', 4), ('c', 7)]
    [('d', 1), ('e', 4), ('f', 7)]
    [('g', 1), ('h', 4), ('i', 7)]
    [('a', 2), ('b', 5), ('c', 8)]
    ...
    

    然后*zip 展开每个元组,itertools.chain.from_iterable() 将它们放在一个列表中。 也可以做到itertools.chain(*zip(lets, nums)) for ...

    接下来,pd.DataFrame.from_records() 为每个列表创建一个数据框行;和生成器表达式创建形成 df 的列表的可迭代。

    【讨论】:

    • 感谢您的代码和解释。不仅可以复制和粘贴,还可以通过我们的 Efford 了解和提高我的知识。我将编辑我的帖子,因为两个数据框都可能包含字母和数字,但我认为使用字母和数字可能会减轻对我正在尝试做的事情的理解。所以再次(我仍在改进如何提出一个好问题)我在这里犯了一个小错误。
    • 是的,字母和数字分开可以说明您正在尝试什么。在我的解决方案中,将其替换为变量leftrightdf1_termsdf2_terms,这样它就与字母或数字无关——只是连接中左边或右边的对。您的问题很好,问得很好,很详细,并且包含了您尝试过的代码。我建议的唯一更改是将df1df2 放在彼此下方而不是并排放置,以便那些试图解决的人可以复制和重新创建它。或者添加代码来创建它们。
    • 感谢您的额外解释以及对解决方案背后动态的更多见解。今天我将在我的代码中实施你的灵魂,你的回答应该在欧洲中部时间 22:00 之前被接受。稍后我将按照您的建议编辑我的问题,谢谢您的提示。
    猜你喜欢
    • 2023-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多