Итерация и условное добавление строковых значений в кадре данных Pandas - PullRequest
0 голосов
/ 22 октября 2018

У меня есть база данных участников исследования, чьи идентификаторы хранятся в следующем формате «0000.000».Где первые четыре цифры - их идентификационный номер семьи, а последние три цифры - их индивидуальный индекс в семье.У большинства пользователей есть суффикс «.000», но у некоторых есть «.001», «.002» и т. Д.

В результате некоторых недостатков эти числа сохраняются как числа с плавающей запятой.Я пытаюсь импортировать их как строки, чтобы я мог использовать их в соединении с другим фреймом данных, который правильно отформатирован.

Эти идентификаторы, заканчивающиеся на .000, импортируются как «0000», а не как «0000.000" .Все остальные импортируются правильно.

Я пытаюсь перебрать идентификаторы и добавить ".000" к тем, у которых отсутствует суффикс.

Если бы я использовал R, я мог бы сделатьэто так.

df %>% mutate(StudyID = ifelse(length(StudyID)<5,
                               paste(StudyID,".000",sep=""),
                               StudyID)

Я нашел решение Python (ниже), но оно довольно неприятное.

row = 0
for i in df["StudyID"]:
    if len(i)<5:
        df.iloc[row,3] = i + ".000"
    else: df.iloc[row,3] = i
    index += 1

Я думаю, что было бы идеально сделать это как понимание списка, но я не смог найти решение, которое позволило бы мне перебирать столбец, меняя одно значение за раз.

Например, это решение правильно выполняет итерацию и проверяет логику, но заменяет каждое отдельное значение, которое оценивает True во время каждой итерации.Я только хочу, чтобы значение, оцениваемое в настоящий момент, изменилось.

[i + ".000" if len(i)<5 else i for i in df["StudyID"]]

Возможно ли это?

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

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

Я думаю, что идея понимания списка идетстановиться слишком сложным и потенциально слишком трудным для понимания при просмотре, поэтому я остановился на простом старом цикле for.

def create_multi_index(data, col_to_split, sep = "."):
    """
    This function loops through the original ID column and splits it into 
        multiple parts (multi-IDs) on the defined separator.
        By default, the function assumes the unique ID is formatted like a decimal number
    The new multi-IDs are appended into a new list. 
        If the original ID was formatted like an integer, rather than a decimal
            the function assumes the latter half of the ID to be ".000"
    """    

    # Take a copy of the dataframe to modify
    new_df = data

    # generate two new lists to store the new multi-index
    Family_ID = []
    Family_Index = []

    # iterate through the IDs, split and allocate the pieces to the appropriate list
    for i in new_df[col_to_split]:

        i = i.split(sep)

        Family_ID.append(i[0])

        if len(i)==1:
            Family_Index.append("000")
        else: 
            Family_Index.append(i[1])

    # Modify and return the dataframe including the new multi-index
    return new_df.assign(Family_ID = Family_ID,
                         Family_Index = Family_Index)

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

При объединении фреймов данных с этой формой идентификатора, если оба фрейма данных имеют мультииндекс в одном формате, эти столбцы можно использовать с pd.merge следующим образом:

pd.merge(df1, df2, how= "inner", on = ["Family_ID","Family_Index"])

0 голосов
/ 22 октября 2018

Как вы сказали, ваш код делает свое дело.Еще один способ сделать то, что вы хотите, о чем я мог подумать, это:

# Start by creating a mask that gives you the index you want to change
mask = [len(i)<5 for i in df.StudyID]
# Change the value of the dataframe on the mask
df.StudyID.iloc[mask] += ".000"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...