如何在python中通过考虑来自其他数据帧的条件来生成新的数据帧?

如何在python中通过考虑来自其他数据帧的条件来生成新的数据帧?,python,pandas,numpy,data-manipulation,Python,Pandas,Numpy,Data Manipulation,我在python中使用pandas对一个非常大的数据集(比如1亿行)执行数据操作。我有两个数据帧,并希望根据上述条件生成第三个数据帧,下面解释该场景: 数据帧1: 列B和列D为int64类型 Col_A Col_B Col_C Col_D A 11 B 20 A 11 C 24 B 14 R 32 ... ... ... ... 数据帧2: 列Z的类

我在
python
中使用
pandas
对一个非常大的数据集(比如1亿行)执行数据操作。我有两个数据帧,并希望根据上述条件生成第三个数据帧,下面解释该场景:

数据帧1:
列B和列D为
int64
类型

Col_A   Col_B   Col_C   Col_D
 A       11      B       20
 A       11      C       24
 B       14      R       32
...      ...    ...      ...
数据帧2:
列Z的类型为
float64
,其余列的类型为
int64

Col_X   Col_Y   Col_P   Col_Q   Col_Z
 10      15      16      21      0.99
 10      15      17      22      0.89
...     ...     ...     ...      ...
...     ...     ...     ...      ...
 11      15      30      35      0.67
...     ...     ...     ...      ...
适用条件: 仅考虑数据框的第一行,为了理解条件:

如果值(Col_B在Col_X和colu Y之间)和值(Col_D在Col_p和colu Q之间),则返回Col_A、Col_C和colu Z的相应值,否则返回NaN

预期输出(数据帧3):

注意:此输出仅考虑数据帧中是否只有这三行,但实际上,数据帧1的每个值必须扫描数据帧2中的所有值,直到达到所需条件

我的代码:

df3={}
Col_A=[]
Col_C=[]
Col_Z=[]
对于df1.ItErrors()中的i:
值=浮点(df2[(i[1][1]>df2['Col_X']值)&
(i[1][1]df2['Col_P']值)&
(i[1][3]
在条件满足之前,此代码正常工作,一旦条件不满足,它将抛出一个
类型错误
。请纠正这一点。


另外,我想知道是否有其他有效的方法来执行它。请让我知道

新答案

你有两个装饰环。第一个总是一个完整的循环。但不是第二个。因此,问题是如何提高子部分循环的效率

在这里,我为您提供两种执行第二个循环的方法:

  • 第一种方法将数据集视为一个整体,处理所有数据并选择感兴趣的值
  • 第二个迭代行,直到匹配条件
这可能会让您了解如何执行迭代

# Import module
import numpy as np

df1 = pd.DataFrame([["A", 11,  "B", 20],
                    ["A", 11,  "C", 24],
                    ["B", 14,  "R", 32]],
                   columns=["Col_A", "Col_B", "Col_C", "Col_D"])
df2 = pd.DataFrame([[10, 15,  16, 21, 0.99],
                    [10, 15,  17, 22, 0.89],
                    [11, 15,  30, 35, 0.67]],
                   columns=["Col_X", "Col_Y", "Col_P", "Col_Q", "Col_Z"])

def getCondition(row, df2):
    # Iterate df2 till a row meets the condition
    for _, row_df2 in df2.iterrows():
        if row_df2.Col_X <= row.Col_B and row.Col_B < row_df2.Col_Y \
            and row_df2.Col_P <= row.Col_D and row.Col_D < row_df2.Col_Q:
            return pd.Series([row.Col_A, row.Col_C, row_df2.Col_Z])
    return np.NaN


def getCondition2(row, df2):
    # Find all rows matching the condition and select the first
    condition = ((df2.Col_X <= row.Col_B) & (row.Col_B < df2.Col_Y)\
        & (df2.Col_P <= row.Col_D) & (row.Col_D < df2.Col_Q))
    if sum(condition) > 0:
        return pd.Series([row.Col_A, row.Col_C, df2.Col_Z[condition].iloc[0]])
    return np.NaN


# Apply the condition
output = df1.apply(getCondition2, args=[df2], axis=1)
print(output)
#      0    1     2
# 0    A    B  0.99
# 1  NaN  NaN   NaN
# 2    B    R  0.67

新答案

你有两个装饰环。第一个总是一个完整的循环。但不是第二个。因此,问题是如何提高子部分循环的效率

在这里,我为您提供两种执行第二个循环的方法:

  • 第一种方法将数据集视为一个整体,处理所有数据并选择感兴趣的值
  • 第二个迭代行,直到匹配条件
这可能会让您了解如何执行迭代

# Import module
import numpy as np

df1 = pd.DataFrame([["A", 11,  "B", 20],
                    ["A", 11,  "C", 24],
                    ["B", 14,  "R", 32]],
                   columns=["Col_A", "Col_B", "Col_C", "Col_D"])
df2 = pd.DataFrame([[10, 15,  16, 21, 0.99],
                    [10, 15,  17, 22, 0.89],
                    [11, 15,  30, 35, 0.67]],
                   columns=["Col_X", "Col_Y", "Col_P", "Col_Q", "Col_Z"])

def getCondition(row, df2):
    # Iterate df2 till a row meets the condition
    for _, row_df2 in df2.iterrows():
        if row_df2.Col_X <= row.Col_B and row.Col_B < row_df2.Col_Y \
            and row_df2.Col_P <= row.Col_D and row.Col_D < row_df2.Col_Q:
            return pd.Series([row.Col_A, row.Col_C, row_df2.Col_Z])
    return np.NaN


def getCondition2(row, df2):
    # Find all rows matching the condition and select the first
    condition = ((df2.Col_X <= row.Col_B) & (row.Col_B < df2.Col_Y)\
        & (df2.Col_P <= row.Col_D) & (row.Col_D < df2.Col_Q))
    if sum(condition) > 0:
        return pd.Series([row.Col_A, row.Col_C, df2.Col_Z[condition].iloc[0]])
    return np.NaN


# Apply the condition
output = df1.apply(getCondition2, args=[df2], axis=1)
print(output)
#      0    1     2
# 0    A    B  0.99
# 1  NaN  NaN   NaN
# 2    B    R  0.67

经过几次试验后,我能够解决我自己的代码。这里是-已纠正的一个:

df3 = {}
Col_A = []
Col_C = []
Col_Z = []
for i in df1.iterrows():    
    value = df2[(i[1][1] > df2['Col_X'].values) &
      (i[1][1] < df2['Col_Y'].values) &
      (i[1][3] > df2['Col_P'].values) &
      (i[1][3] < df2['Col_Q'].values)]['Col_Z']

    if value.empty:
        continue
    else:
        Col_Z.append(value)
        Col_A.append(i[1][0])
        Col_C.append(i[1][2])

df3['A'] = Col_A
df3['C'] = Col_C
df3['Z'] = Col_Z
df3 = pd.DataFrame(df3)
df3={}
Col_A=[]
Col_C=[]
Col_Z=[]
对于df1.ItErrors()中的i:
value=df2[(i[1][1]>df2['Col_X'].值)&
(i[1][1]df2['Col_P']值)&
(i[1][3]
然而,由于
for
循环在所有行上进行迭代,这种方法对于大型数据集(比如1-2亿)可能并不有效。
希望能找到一些更有效的方法

经过几次尝试后,我能够解决我自己的代码。这里是-已纠正的一个:

df3 = {}
Col_A = []
Col_C = []
Col_Z = []
for i in df1.iterrows():    
    value = df2[(i[1][1] > df2['Col_X'].values) &
      (i[1][1] < df2['Col_Y'].values) &
      (i[1][3] > df2['Col_P'].values) &
      (i[1][3] < df2['Col_Q'].values)]['Col_Z']

    if value.empty:
        continue
    else:
        Col_Z.append(value)
        Col_A.append(i[1][0])
        Col_C.append(i[1][2])

df3['A'] = Col_A
df3['C'] = Col_C
df3['Z'] = Col_Z
df3 = pd.DataFrame(df3)
df3={}
Col_A=[]
Col_C=[]
Col_Z=[]
对于df1.ItErrors()中的i:
value=df2[(i[1][1]>df2['Col_X'].值)&
(i[1][1]df2['Col_P']值)&
(i[1][3]
然而,由于
for
循环在所有行上进行迭代,这种方法对于大型数据集(比如1-2亿)可能并不有效。
希望能找到一些更有效的方法

很高兴知道。你能用一个更相关的例子(不同的行数)更新这个问题吗。不知道条件是如何计算的,你能解释一下吗?对不起,我无意中删除了最后一条评论。在我的解释中,我已经更新了dataframe 2表。我无法连接和应用条件,因为首先,两个dataframe的大小不相等,这将生成大量不需要的NaN值,加上dataframe 2就像一个查找表,来自dataframe 1 Col_B或Col_D的值,不一定在dataframe 2 Col的同一索引中,因此它需要扫描整个dataframe 2,然后确定需要返回哪个Col_A和Col_C以及Col_Z。我的意思是dataframe 2中的行可以在任何行中,dataframe 1表的值需要搜索它所在的位置并拉出Col_A的相应值,上校,上校,但根据我的情况,总是会有这样一场争吵,只有每一次好的时候才知道。你能用一个更相关的例子(不同的行数)更新这个问题吗。不知道条件是如何计算的,你能解释一下吗?对不起,我无意中删除了最后一条评论。我在解释中更新了dataframe 2表。我无法连接和应用条件,因为首先,两个dataframe的大小不相等,这将生成大量不需要的NaN值,加上dataframe 2就像一个查找表,val
df3 = {}
Col_A = []
Col_C = []
Col_Z = []
for i in df1.iterrows():    
    value = df2[(i[1][1] > df2['Col_X'].values) &
      (i[1][1] < df2['Col_Y'].values) &
      (i[1][3] > df2['Col_P'].values) &
      (i[1][3] < df2['Col_Q'].values)]['Col_Z']

    if value.empty:
        continue
    else:
        Col_Z.append(value)
        Col_A.append(i[1][0])
        Col_C.append(i[1][2])

df3['A'] = Col_A
df3['C'] = Col_C
df3['Z'] = Col_Z
df3 = pd.DataFrame(df3)