【问题标题】:Isolating Adjacent columns based on str.contains基于 str.contains 隔离相邻列
【发布时间】:2017-12-30 14:52:45
【问题描述】:

大家好,所以我的数据框看起来像这样:

 A |  B   |   C | D | E
    'USD'
   'trading expenses-total'   
      8.10   2.3   5.5
      9.1    1.4   6.1
      5.4    5.1   7.8

我还没有找到类似的东西,如果这是重复的,我深表歉意。但本质上,我试图找到包含字符串“总计”(B 列)及其相邻列(C 和 D)的列,并将它们转换为数据框。我觉得我很接近以下代码:

test.loc[:,test.columns.str.contains('total')]

它隔离了正确的列,但我不太清楚如何抓取相邻的两列。我想要的输出是:

 B   |                      C  |  D 
'USD'
'trading expenses-total'   
 8.10                       2.3   5.5
 9.1                        1.4   6.1
 5.4                        5.1   7.8

【问题讨论】:

  • 那里的数据结构看起来很有趣。你能把它清理一下或给出生成该数据结构的代码吗?
  • @ScottBoston 完整的代码有点复杂,但我在数据框中的数字只是虚拟数字。
  • 那是多索引列索引吗?
  • @ScottBoston 很抱歉造成混淆,这些列只是 A、B、C、D、E,我把总这个词放在 B 下以说明我需要 B 列和以下两列。跨度>

标签: python python-3.x pandas numpy


【解决方案1】:

旧答案:

熊猫方法:

In [36]: df = pd.DataFrame(np.random.rand(3,5), columns=['A','total','C','D','E'])

In [37]: df
Out[37]:
          A     total         C         D         E
0  0.789482  0.427260  0.169065  0.112993  0.142648
1  0.303391  0.484157  0.454579  0.410785  0.827571
2  0.984273  0.001532  0.676777  0.026324  0.094534

In [38]: idx = np.argmax(df.columns.str.contains('total'))

In [39]: df.iloc[:, idx:idx+3]
Out[39]:
      total         C         D
0  0.427260  0.169065  0.112993
1  0.484157  0.454579  0.410785
2  0.001532  0.676777  0.026324

更新:

In [118]: df
Out[118]:
     A                       B    C    D     E
0  NaN                     USD  NaN  NaN   NaN
1  NaN  trading expenses-total  NaN  NaN   NaN
2    A                    8.10  2.3  5.5  10.0
3    B                     9.1  1.4  6.1  11.0
4    C                     5.4  5.1  7.8  12.0

In [119]: col = df.select_dtypes(['object']).apply(lambda x: x.str.contains('total').any()).idxmax()

In [120]: cols = df.columns.to_series().loc[col:].head(3).tolist()

In [121]: col
Out[121]: 'B'

In [122]: cols
Out[122]: ['B', 'C', 'D']

In [123]: df[cols]
Out[123]:
                        B    C    D
0                     USD  NaN  NaN
1  trading expenses-total  NaN  NaN
2                    8.10  2.3  5.5
3                     9.1  1.4  6.1
4                     5.4  5.1  7.8

【讨论】:

  • 您好@MaxU 感谢您的回复,但是我收到了 len() of unsized object 的错误。如果有帮助,total 这个词在列中,而不是列名
  • @codeninja,你能发布一个可重现的数据集和想要的数据集吗?
  • 我已经编辑了表格,希望它对我想要实现的目标有所帮助
  • @codeninja,对不起,我不明白你的样本数据集.... 'USD''trading expenses-total' 属于同一行吗?前两行的其他列的值在哪里?
  • 'USD'和'trading costs-total'属于B的同一列,所以'USD'在第一行,'trading costs-total'属于第二行。 C 和 D 在对应的行中没有值
【解决方案2】:

这是一种方法 -

from scipy.ndimage.morphology import binary_dilation as bind

mask = test.columns.str.contains('total')
test_out = test.iloc[:,bind(mask,[1,1,1],origin=-1)]

如果你无权访问SciPy,你也可以使用np.convolve,像这样-

test_out = test.iloc[:,np.convolve(mask,[1,1,1])[:-2]>0]

样本运行

案例#1:

In [390]: np.random.seed(1234)

In [391]: test = pd.DataFrame(np.random.randint(0,9,(3,5)))

In [392]: test.columns = [['P','total001','g','r','t']]

In [393]: test
Out[393]: 
   P  total001  g  r  t
0  3         6  5  4  8
1  1         7  6  8  0
2  5         0  6  2  0

In [394]: mask = test.columns.str.contains('total')

In [395]: test.iloc[:,bind(mask,[1,1,1],origin=-1)]
Out[395]: 
   total001  g  r
0         6  5  4
1         7  6  8
2         0  6  2

案例#2:

如果您有多个匹配列,并且如果您超出限制并且匹配列右侧没有两列,这也有效 -

In [401]: np.random.seed(1234)

In [402]: test = pd.DataFrame(np.random.randint(0,9,(3,7)))

In [403]: test.columns = [['P','total001','g','r','t','total002','k']]

In [406]: test
Out[406]: 
   P  total001  g  r  t  total002  k
0  3         6  5  4  8         1  7
1  6         8  0  5  0         6  2
2  0         5  2  6  3         7  0

In [407]: mask = test.columns.str.contains('total')

In [408]: test.iloc[:,bind(mask,[1,1,1],origin=-1)]
Out[408]: 
   total001  g  r  total002  k
0         6  5  4         1  7
1         8  0  5         6  2
2         5  2  6         7  0

【讨论】:

  • 谢谢@Divakar!不幸的是,由于技术的限制,我无法使用复杂的库
  • 感谢编辑!不幸的是,输出返回原始 df 的所有行,但没有列。它还返回了运行时警告。我觉得这是一个将 mask = test.columns.str.contains('total') 变成一个值以便使用 iloc 的问题,但我将不得不进行更多实验
猜你喜欢
  • 2022-12-04
  • 2018-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-16
  • 1970-01-01
相关资源
最近更新 更多