Pandas按列值拆分DataFrame

146*_*ian 51 python indexing split dataframe pandas

我有DataFrame专栏Sales.

如何根据Sales价值将其拆分为2 ?

首先DataFrame是数据,'Sales' < s第二个是'Sales' >= s

jez*_*ael 67

你可以使用boolean indexing:

df = pd.DataFrame({'Sales':[10,20,30,40,50], 'A':[3,4,7,6,1]})
print (df)
   A  Sales
0  3     10
1  4     20
2  7     30
3  6     40
4  1     50

s = 30

df1 = df[df['Sales'] >= s]
print (df1)
   A  Sales
2  7     30
3  6     40
4  1     50

df2 = df[df['Sales'] < s]
print (df2)
   A  Sales
0  3     10
1  4     20
Run Code Online (Sandbox Code Playgroud)

它也可以mask通过~以下方式反转:

mask = df['Sales'] >= s
df1 = df[mask]
df2 = df[~mask]
print (df1)
   A  Sales
2  7     30
3  6     40
4  1     50

print (df2)
   A  Sales
0  3     10
1  4     20
Run Code Online (Sandbox Code Playgroud)
print (mask)
0    False
1    False
2     True
3     True
4     True
Name: Sales, dtype: bool

print (~mask)
0     True
1     True
2    False
3    False
4    False
Name: Sales, dtype: bool
Run Code Online (Sandbox Code Playgroud)

  • 有没有办法做到这一点,而不必两次切片数据帧?因为这种方式我们必须滚动索引onve来创建df1,另一次滚动df2完全相同的条件.但我无法弄清楚如何将两个数据帧都放在一行中. (5认同)

Zer*_*ero 36

使用groupby你可以分成两个数据帧,如

In [1047]: df1, df2 = [x for _, x in df.groupby(df['Sales'] < 30)]

In [1048]: df1
Out[1048]:
   A  Sales
2  7     30
3  6     40
4  1     50

In [1049]: df2
Out[1049]:
   A  Sales
0  3     10
1  4     20
Run Code Online (Sandbox Code Playgroud)

  • 此操作似乎比 jezrael 的两个选项要贵得多,尽管在语法上更优雅 imo (3认同)
  • 这并不完全等同于 jezrael 的选项。如果拆分后的数据集之一为空,则 group by 将返回仅包含一个元素的列表,并且将无法解压缩为 df1 和 df2。 (3认同)

小智 31

使用“groupby”和列表理解:

将所有拆分的数据帧存储在列表变量中,并通过索引访问每个分离的数据帧。

DF = pd.DataFrame({'chr':["chr3","chr3","chr7","chr6","chr1"],'pos':[10,20,30,40,50],})
ans = [pd.DataFrame(y) for x, y in DF.groupby('chr', as_index=False)]
Run Code Online (Sandbox Code Playgroud)

像这样访问分离的 DF:

ans[0]
ans[1]
ans[len(ans)-1] # this is the last separated DF
Run Code Online (Sandbox Code Playgroud)

像这样访问分离的 DF 的列值:

ansI_chr=ans[i].chr 
Run Code Online (Sandbox Code Playgroud)

  • 我认为你可以简化为 `ans = [y for x, y in DF.groupby('chr', as_index=False)]` 因为 y 已经是一个 DataFrame (10认同)
  • 这个答案并不取决于分割的数量。它应该被投票为 #1 只需要根据 @C8H10N4O2 的评论更新它 (2认同)

Myk*_*tko 17

使用海象运算符的单行代码(Python 3.8):

df1, df2 = df[(mask:=df['Sales'] >= 30)], df[~mask]
Run Code Online (Sandbox Code Playgroud)

考虑使用copy以避免SettingWithCopyWarning

df1, df2 = df[(mask:=df['Sales'] >= 30)].copy(), df[~mask].copy()
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用以下方法query

df1, df2 = df.query('Sales >= 30').copy(), df.query('Sales < 30').copy()
Run Code Online (Sandbox Code Playgroud)


小智 11

我喜欢用它来加速搜索或滚动平均查找 .apply(lambda x...) 类型的函数,因此我将大文件拆分为数据帧的字典:

df_dict = {sale_v: df[df['Sales'] == sale_v] for sale_v in df.Sales.unique()}
Run Code Online (Sandbox Code Playgroud)

如果您想基于分类组进行操作,这应该可以做到。