How to filter columns, all 0s in Python?

I have some structures that need to be filtered. Is there a way to make this beautiful in Python?

I have an ugly way to do this, but I want to clear it:

original_header = ['a','b','c'] original_rows = [[1,0,1], [0,0,0], [1,0,0]] processed_header, processed_rows = some_cool_utility(original_header, original_rows) assert_equals(['a', 'c'], processed_header) assert_equals([[1,1], [0,0], [1,0]], processed_rows) 
+7
source share
6 answers
 original_header = ['a','b','c'] original_rows = [[1,0,1], [0,0,0], [1,0,0]] #transpose rows to get columns columns = zip(*original_rows) #build list which is true if the column should be kept (is not a column of all zeros) not_all_zero = [ any(x) for x in columns ] #filter the lists based on columns processed_header = [x for i,x in enumerate(original_header) if not_all_zero[i] ] processed_columns = [ x for i,x in enumerate(columns) if not_all_zero[i] ] #transpose the remaining columns back into rows. processed_rows = zip(*processed_columns) print (processed_header) #['a', 'c'] print (processed_rows) #[(1, 1), (0, 0), (1, 0)] 

Note that this returns a list of tuples instead of a list of lists. If you really need a list of lists, you can simply processed_rows = map(list, processed_rows)

+5
source

Use numpy

 import numpy as np original_rows = np.asarray([[1,0,1], [0,0,0], [1,0,0]]) original_labels = np.asarray(["a", "b", "c"]) # Get locations where columns are all zeros. nonzero_cols = np.any(original_rows!=0, axis=0) # Get data only where column is not all zeros. nonzero_data = original_rows[:, nonzero_cols] nonzero_labels = original_labels[nonzero_cols] 
+5
source

This should work:

 >>> original_header = ['a','b','c'] >>> original_rows = [[1,0,1], [0,0,0], [1,0,0]] >>> row_major = zip(*original_rows) >>> filtered = [(h, col) ... for h, col ... in zip(original_header, row_major) ... if any(col)] >>> header, rows = zip(*filtered) >>> header ('a', 'c') >>> rows ((1, 0, 1), (1, 0, 0)) >>> zip(*rows) [(1, 1), (0, 0), (1, 0)] >>> 

edit: fixed; added transposition to the filtered list view, in fact I didn’t look hard enough

+2
source

If you're not stuck in a data format, storing data as a dictionary makes this a lot easier:

 original_header = ['a','b','c'] original_rows = [[1,0,1], [0,0,0], [1,0,0]] # Restructure data into easier-to-process dict to_dict = dict(zip(original_header, zip(*original_rows))) print to_dict # {'a': (1, 0, 1), 'b': (0, 0, 0), 'c': (1, 0, 0)} # Filter out keys with all-zero values filtered_dict = {k:v for (k, v) in dictify.items() if not all(x==0 for x in v)} print filtered_dict # Output: {'a': (1, 0, 1), 'c': (1, 0, 0)} 
+1
source

The following works:

 all_rows = original_rows[:] #make a copy all_rows.insert(0, original_header) all_columns = list(zip(*all_rows)) #transpose filtered_columns = [col for col in all_columns if any(col[1:])] #remove columns that only contain 0's filtered_rows = [list(tp) for tp in zip(*filtered_columns)] #transpose back, convert each element to a list processed_header = filtered_rows[0] processed_rows = filtered_rows[1:] 
0
source

For write only:

 def some_cool_utility(header, rows): data = [element for element in zip(header, rows) if any(element[1])] head, rows = zip(*data) return head, rows 
0
source

All Articles