简体   繁体   中英

Aggregate values of same name pandas dataframe columns to single column

I have multiple csv files that were produced by tokenizing code. These files contain keywords in uppercase and lowercase. I would like to merge all those files in one single dataframe which contains all the unique values (summed) in lowercase. What would you suggest to get the result below?

Initial DF:

+---+---+----+-----+
| a | b |  A |  B  |
+---+---+----+-----+
| 1 | 2 |  3 |   1 |
| 2 | 1 |  3 |   1 |
+---+---+----+-----+

Result

+---+---+
| a | b |
+---+---+
| 4 | 3 |
| 5 | 2 |
+---+---+

I don't have access to the raw data from which the csv files where created so I cannot correct this at an earlier step. At the moment I have tried mapping .lower() to the dataframe headers that I create, but it returns seperate columns with the same name like so:

.lower()合并后

Using pandas is not essential. I have thought of converting the csv files to dictionaries and then trying the above procedure (turns out it is much more complicated than I thought), or using lists. Also, group by does not do the job as it will remove non duplicate column names. Any approach is welcome.

The below solution should do:

import pandas as pd
import numpy as np 

np.random.seed(seed=1902)

test_df = pd.DataFrame({
    # some ways to create random data
    'a': np.random.randint(9, size=5),
    'b': np.random.randint(9, size=5),
    'A': np.random.randint(9, size=5),
    'B': np.random.randint(9, size=5),
    'c': np.random.randint(9, size=5),
})

sum_df = test_df.copy()
columns_to_keep = set([name.lower() for name in list(test_df)])

for column_name in columns_to_keep:
    mutual_columns = [column_name, column_name.upper()]
    mutual_columns = [value for value in mutual_columns if value in list(test_df)]
    sum_df[column_name] = test_df[mutual_columns].sum(axis=1)

sum_df = sum_df[list(columns_to_keep)]
print("original is:\n", test_df)
print("sum is:\n", sum_df)

producing

original is:
    a  b  A  B  c
0  2  5  7  2  4
1  1  6  2  3  1
2  0  4  2  4  3
3  6  5  5  7  4
4  1  0  2  7  5

sum is:
     a   b  c
0   9   7  4
1   3   9  1
2   2   8  3
3  11  12  4
4   7  5   3

basically make a list of mutual columns to sum (given by the name of the column and their corresponding upper or lower, respectively) and sum along the rows in correspondence of those ones only.

Code:

You could iterate through the columns summing those that have the same lowercase representation:

def sumDupeColumns(df):
    """Return dataframe with columns with the same lowercase spelling summed."""

    # Get list of unique lowercase column headers
    columns = set(map(str.lower, df.columns))
    # Create new (zero-initialised) dataframe for output
    df1 = pd.DataFrame(data=np.zeros((len(df), len(columns))), columns=columns)

    # Sum matching columns
    for col in df.columns:
        df1[col.lower()] += df[col]

    return df1

Example:

import pandas as pd
import numpy as np

np.random.seed(seed=42)

# Generate DataFrame with random int input and 'duplicate' columns to sum
df = pd.DataFrame(columns = ['a','A','b','B','Cc','cC','d','eEe','eeE','Eee'], 
                  data = np.random.randint(9, size=(5,10))

df = sumDupeColumns(df)

>>> print(df)

     d   eee   cc     a     b
0  6.0  14.0  8.0   9.0  11.0
1  7.0  10.0  5.0  14.0   7.0
2  3.0  14.0  8.0   5.0   8.0
3  3.0  17.0  7.0   8.0  12.0
4  0.0  11.0  9.0   5.0   9.0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM