Pandas добавляет повторяющиеся строки, даже если оператор if не должен запускаться - PullRequest
0 голосов
/ 09 июля 2020

У меня много файлов CSV, в которых есть только одна строка данных. Мне нужно взять данные из двух ячеек и поместить их в главный файл csv ('new_gal.csv'). Первоначально он будет содержать только заголовки, но не данные.

#The file I am pulling from:
 file_name = "N4261_pacs160.csv"
#I have the code written to separate gal_name, cat_name, and cat_num (N4261, pacs, 160)

Здесь приведен пример csv. Я пытаюсь вытащить из этого файла "поток" и "среднеквадратичное значение". (Извините, он плохо выровнен; я не могу понять форматирование).

name  band  ra  dec  raerr  decerr  flux  snr  snrnoise  stn  rms  strn  fratio  fwhmxfit  fwhmyfit  flag_elong  edgeflag  flag_blend  warmat 
 obsid  ssomapflag  dist  angle
HPPSC160A_J121923.1+054931  red  184.846389  5.8254  0.000151  0.00015 
 227.036  10.797  21.028  16.507  13.754  37.448  1.074  15.2  11  0.7237 
 f  0  f  1342199758  f  1.445729  296.577621

Я читаю этот CSV и извлекаю данные, которые мне нужны

with open(file_name, 'r') as table:
    reader = csv.reader(table, delimiter=',')
    read = iter(reader)
    next(read)
    for row in read:
        fluxP = row[6]
        errP = row[10]
#Open the master csv with pandas
df = pd.read_csv('new_gal.csv')

Главный CSV Файл имеет формат:

Galaxy  Cluster Mult. Detect.   LumDist z   W1  W1 err  W2  W2 err  W3  W3 err  W4  W4 err  70  70 err  100 100 err 160 160 err 250 250 err 350 350 err 500 500 err

                                                                                            

Основная проблема, с которой я сталкиваюсь, заключается в том, что я хочу выполнить поиск в столбце «Галактика» в файле new_gal.csv по названию галактики. Если его там нет, мне нужно добавить новую строку с названием галактики и измерением потока и погрешности. Когда я запускаю это несколько раз, я получаю повторяющиеся строки, хотя у меня есть команда добавления, вложенная в оператор if. Я хочу, чтобы он только добавил новую строку, если названия галактики еще нет; в противном случае он должен изменить только значения потоков и измерений ошибок для этой галактики.

if cat_name == 'pacs':
    if gal_name not in df["Galaxy"]:
        df = df.append({"Galaxy": gal_name}, ignore_index=True)
        if cat_num == "70":
            df.loc[df.Galaxy == gal_name, ["70"]] = fluxP
            df.loc[df.Galaxy == gal_name, ["70 err"]] = errP
        elif cat_num == "100":
            df.loc[df.Galaxy == gal_name, ["100"]] = fluxP
            df.loc[df.Galaxy == gal_name, ["100 err"]] = errP
        elif cat_num == "160":
            df.loc[df.Galaxy == gal_name, ["160"]] = fluxP
            df.loc[df.Galaxy == gal_name, ["160 err"]] = errP
    else:
        if cat_num == "70":
            df.loc[df.Galaxy == gal_name, ["70"]] = fluxP
            df.loc[df.Galaxy == gal_name, ["70 err"]] = errP
        elif cat_num == "100":
            df.loc[df.Galaxy == gal_name, ["100"]] = fluxP
            df.loc[df.Galaxy == gal_name, ["100 err"]] = errP
        elif cat_num == "160":
            df.loc[df.Galaxy == gal_name, ["160"]] = fluxP
            df.loc[df.Galaxy == gal_name, ["160 err"]] = errP

После запуска кода 5 раз с одним и тем же файлом у меня есть 5 одинаковых строк в таблице.

1 Ответ

0 голосов
/ 10 июля 2020

Думаю, у меня есть кое-что, что будет работать после того, как поработал с ним сегодня утром ...

Пара очков ... Вы не должны постепенно наращивать pandas ... получить данные настройка выполняется извне, затем выполните 1 сборку. В том, что у меня ниже, я создаю большой словарь из небольших файлов csv, а затем использую слияние, чтобы объединить его с основным файлом.

Если ваши файлы .csv не отформатированы должным образом, вы можете либо попробуйте заменить разделенный символ ниже, либо переключитесь на программу чтения csv, которая немного мощнее.

Вы должны поместить все меньшие файлы .csv в папку с именем 'orig_data', чтобы эта работа работала .

основная программа

# galaxy compiler
import os, re
import pandas as pd

# folder location for the small .csvs, NOT the master
data_folder = 'orig_data'  # this folder should be in same directory as program

result = {}
splitter = r'(.+)_([a-zA-Z]+)([0-9]+)\.'  # regex to break up file name into 3 groups

for file in os.listdir(data_folder):
    file_data = {}
    # split up the filename and process
    galaxy, cat_name, cat_num = re.match(splitter, file).groups()
    #print(galaxy, cat_name, cat_num)
    with open(os.path.join(data_folder, file), 'r') as src:
        src.readline()   # read the header and disregard it
        data = src.readline().replace(' ','').strip().split(',') # you can change the split char
        flux = float(data[2])
        rms = float(data[3])
    err_tag = cat_num + ' err'
    file_data = {   'cat_name': cat_name, 
                    cat_num:    flux,
                    err_tag:    rms}
    result[galaxy] = file_data

df2 = pd.DataFrame.from_dict(result, orient='index')
df2.index.rename('galaxy', inplace=True)

# check the resulting build!
#print(df2)

# build master dataframe
master_df = pd.read_csv('master_data.csv')
#print(master_df.head())

# merge the 2 dataframes on galaxy name.  See the dox on merge for other
# options and whether you want an "outer" join or other type of join...
master_df = master_df.merge(df2, how='outer', on='galaxy')

# convert boolean flags properly
conv = {'t': True, 'f': False}
master_df['flag_nova'] = master_df['flag_nova'].map(conv).astype('bool')

print(master_df)
print()
print(master_df.info())
print()
print(master_df.describe())

примеры файлов данных в orig_data папке

filename: A99_dbc100.csv

band,weight,flux,rms
junk, 200.44,2e5,2e-8

filename: B250_pacs100. csv

band,weight,flux,rms
nada,2.44,19e-5, 74

... et c.

пример мастер csv

galaxy,color,stars,flag_nova
A99,red,15,f
B250,blue,4e20,t
N1000,green,3e19,f
X99,white,12,t

Результат:

  galaxy  color         stars  ...  200 err           100       100 err
0    A99    red  1.500000e+01  ...      NaN  200000.00000  2.000000e-08
1   B250   blue  4.000000e+20  ...      NaN       0.00019  7.400000e+01
2  N1000  green  3.000000e+19  ...     88.0           NaN           NaN
3    X99  white  1.200000e+01  ...      NaN           NaN           NaN

[4 rows x 9 columns]

<class 'pandas.core.frame.DataFrame'>
Int64Index: 4 entries, 0 to 3
Data columns (total 9 columns):
galaxy       4 non-null object
color        4 non-null object
stars        4 non-null float64
flag_nova    4 non-null bool
cat_name     3 non-null object
200          1 non-null float64
200 err      1 non-null float64
100          2 non-null float64
100 err      2 non-null float64
dtypes: bool(1), float64(5), object(3)
memory usage: 292.0+ bytes
None

              stars        200  200 err            100       100 err
count  4.000000e+00        1.0      1.0       2.000000  2.000000e+00
mean   1.075000e+20  1900000.0     88.0  100000.000095  3.700000e+01
std    1.955121e+20        NaN      NaN  141421.356103  5.232590e+01
min    1.200000e+01  1900000.0     88.0       0.000190  2.000000e-08
25%    1.425000e+01  1900000.0     88.0   50000.000143  1.850000e+01
50%    1.500000e+19  1900000.0     88.0  100000.000095  3.700000e+01
75%    1.225000e+20  1900000.0     88.0  150000.000048  5.550000e+01
max    4.000000e+20  1900000.0     88.0  200000.000000  7.400000e+01
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...